Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Поиск в SP / 19 сообщений из 19, страница 1 из 1
11.09.2002, 12:28:21
    #32049639
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Hi all!
Есть SP с несколькими параметрами например int и datetime
Мне надо выбрать данные согласно этим параметрам. Проблеиа: если один или несколько параметров будут= NULL ясно ничего не выйдет. Как можно обойти использование sqlexec.
Зараннее всем очень признателен :)
...
Рейтинг: 0 / 0
11.09.2002, 12:33:14
    #32049643
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Код: plaintext
...where (a=@a or @a is null) and  (b=@b or @b is null)...
...
Рейтинг: 0 / 0
11.09.2002, 12:35:32
    #32049645
ziktuw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
... WHERE (SomeIntField=@ParamInt or @ParamInt is NULL) and (SomeDateField=@ParamDate or @ParamDate is NULL) ...

Такую SP лучше делать с указанием WITH RECOMPILE

А реально эффективнее в большинстве случаев запуска этой SP будет все же, если внутри строить динамический запрос и выполнять через EXEC или sp_executesql, так как каждый раз будет выбран самый эффективный план запроса.
...
Рейтинг: 0 / 0
11.09.2002, 12:37:32
    #32049646
vadim_march
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
To Hi: What's up all? ("свистать всех наверх?") :)
>>Как можно обойти использование sqlexec
т.е. запустить хп не запуская?
...
Рейтинг: 0 / 0
11.09.2002, 12:59:34
    #32049656
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2Dankov
Нужно избегать использовать sp_executesql - придётся давать права на таблицы.
...
Рейтинг: 0 / 0
11.09.2002, 13:35:27
    #32049677
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2 Dankov & alexeyvg
В точку!!! (впрочем как всегда :)
Мне нельзя давать прав на чтение таблиц, весь интерфейс только через SP. И в этом случае насколько я понял можно только так: where (a=@a or @a is null) and (b=@b or @b is null)...
НО Смущает:
>>Такую SP лучше делать с указанием WITH RECOMPILE
Именно эти таблицы предполагаются "объемными"
почему подобный подход заведомо не эффективен?
...
Рейтинг: 0 / 0
11.09.2002, 13:56:37
    #32049690
ziktuw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Потому что для конструкции (a=@a or @a is null) вряд ли будет использован индекс на поле "a", если таковой есть.
...
Рейтинг: 0 / 0
11.09.2002, 14:25:31
    #32049712
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2 Dankov
Это полохо :( Очень полохо :(
А WITH RECOMPILE чем поможет?
...
Рейтинг: 0 / 0
11.09.2002, 14:38:11
    #32049717
ziktuw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Точнее, может помочь. Если от значения параметров весьма зависит алгоритм, то лучше будет, если план будет строиться кажный раз заново. А этот случай именно такой. Поэтому и RECOMPILE.
...
Рейтинг: 0 / 0
11.09.2002, 15:43:32
    #32049740
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
К сожалению, в конструкции (a=@a or @a is null) and (b=@b or @b is null) будет использован индекс по "a"
Причём with recompile не помогает :-(

И скорость (и к-во чтений страниц) получается в 100000 (сто тысяч) раз хуже, чем при разделении запросов
Это на небольшой таблице (1.5 млн записей)

Может, конечно, при проверке были какие-нибуть случайности, типа неправильной статистики...
...
Рейтинг: 0 / 0
11.09.2002, 15:53:00
    #32049746
av_ev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Я обычно поступаю примерно так:

1. Пишу процедуру поиска по 1 параметру (желательно в индексированном поле)

2. Получаю рекордсет

3. К рекордсету применяю дополнительные фильтры

4. Вывожу результат

Все работает очень шустро
...
Рейтинг: 0 / 0
11.09.2002, 16:35:48
    #32049773
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2 alexeyvg
>>И скорость ..получается в 100000 раз хуже, чем при разделении запросов
т.е запросы можно разделить ? КАК?
...
Рейтинг: 0 / 0
11.09.2002, 17:08:28
    #32049798
VVG_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Где-то тут видел такой вариант:

Код: plaintext
... where isnull(@a,- 1 ) in (a,- 1 )

Понятно, что в базе не нулл и можно подобрать фиктивное значение для параметра.
...
Рейтинг: 0 / 0
11.09.2002, 18:41:21
    #32049840
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
два варианта

Код: plaintext
1.
2.
SET @a = ISNULL(@a, 0 )
...
where @a = CASE @a WHEN  0  THEN  0  ELSE a END

Код: plaintext
where a = ISNULL(@a,a)

попробуй оба, сообщи результаты.
...
Рейтинг: 0 / 0
12.09.2002, 11:21:57
    #32049956
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2Hi
Я имел в виду - по сравнению с двумя раздельными запросами:
where a=@a
и
where b=@b

Кстати, мне пришла в голову мысль - самое эффективное сделать union:
select...
from...
where a=@a
union
select...
from...
where b=@b
...
Рейтинг: 0 / 0
12.09.2002, 12:42:44
    #32050010
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Спасибо всем за участие :)
"Истина где-то рядом.." попробую объяснить всю ситуацию :-Р. У меня есть 4 таблицы, по сути фича для обмена MSG и все что надо это обычный ФИЛЬТР:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE TABLE [User](
	[UserID] [int] NOT NULL 
)

CREATE TABLE [Task](
	[TaskID] [int] NOT NULL,
	[TaskSubject] [varchar] ( 2048 ) NOT NULL,
	[TaskPriority] [tinyint] NOT NULL,
	[TaskSentDate] [datetime] NOT NULL DEFAULT (getdate()),
	[TaskReadDate] [datetime] NULL

)
CREATE TABLE [InBox](
	[UserID] [int] NOT NULL,
	[TaskID] [int] NOT NULL,
	[ReadDate] [datetime] NULL
)
CREATE TABLE [OutBox](
	[UserID] [int] NOT NULL,
	[TaskID] [int] NOT NULL,
)

Все ID есно PRIMARY, CLUSTERED
Как я уже сказал требуется обыкновенный фильтр.
Task.TaskPriority, Task.TaskSendDate, Task.TaskReadDate, Inbox.UserID, Inbox.ReadDate и т.д.
- Использование динамического запроса исключенно (доступ к таблицам закрыт).
- Понятно что если передаваемый параметр null, то требуются все записи для по соответствующему полю,
т.е. что-то вроде where @a = ISNULL(@a,0) не подходит, поскольку если NULL то ну ANY что ли :)
здесь наверное можно подменить только даты
с -> ISNULL(@ReadDate, '01/01/1700') или
по -> ISNULL(@ReadDate, getdate())
А что с INT делать ?
- ну и последнее. Все должно начинаться в Outbox т.к там собственно храняться доступные для фильтрации MSG TaskID

2 alexeyvg
>>самое эффективное сделать union:
Может я не понял идеи. но помоему union вернет "объединение". а мне то как раз требуется "пересечение" по всем условиям.
Или у вас была другая идея?
...
Рейтинг: 0 / 0
12.09.2002, 14:17:48
    #32050076
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Что-то не совсем понятно, что надо!
Ты бы написал SELECT-ы с вариантами условий, как если бы ты делал через динамик и написал по русски, какие условия должны быть. Тогда, возможно, кто-нибудь тебе и поможет.
...
Рейтинг: 0 / 0
12.09.2002, 15:26:22
    #32050124
Hi
Hi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
Возможно вы правы. В этом запросе я попытался использовать советы
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
DECLARE @SenderID int
DECLARE @WorkerID int
DECLARE @Priority tinyint
DECLARE @SendDateFrom datetime
DECLARE @SendDateTo datetime

SELECT	dbo.Task.TaskID
FROM	dbo.Task 
	  INNER JOIN dbo.InBox ON dbo.Task.TaskID = dbo.InBox.TaskID
	  INNER JOIN dbo.OutBox ON dbo.Task.TaskID = dbo.OutBox.TaskID
WHERE (dbo.OutBox.UserID = @SenderID OR @SenderID IS NULL)
	AND (dbo.InBox.UserID = @WorkerID OR @WorkerID IS NULL)
	AND (dbo.Task.TaskImportance = @Priority OR @Priority IS NULL)
	AND (dbo.Task.TaskSentDate > ISNULL(@SendDateFrom, '01/01/1753')
	AND (dbo.Task.TaskSentDate < ISNULL(@SendDateTo, '31/12/9999')

Как я понял здесь будет использован только индекс по OutBox.UserID, а InBox.UserID будет опущен. Это будет очевидный провал в поизводительности, поскольку MSG может быть групповым(нескольким UserID) поэтому в Inbox может быть до черта записей по одному TaskID
...
Рейтинг: 0 / 0
12.09.2002, 15:38:46
    #32050128
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в SP
2Hi
Виноват, забыл:

select...
from...
where a=@a and @b is null
union
select...
from...
where b=@b and @a is null
union
select...
from...
where a=@a and b=@b

Но если условий много, то писать неудобно
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Поиск в SP / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]