Ellin пишет:
> идентификатором равным входному параметру. Если идентификатор равен 0, > то нужно возвращать все записи. Как в таких случаях писать. Мне почему > то подход в стиле:
> Не очень нравится. Есть другие пути решения?
А зря он тебе не нравится. Наоборот, это -- хороший
подход. Потому что писать сложные условия в одном
запросе -- только путать оптимизатор. Делают
даже ещё "кривее" с твоей точки зрения -- пишут
эти два запроса в разных процедурах, которые
возможно вызываются по аналогичному условию(ям) из одной главной,
зовущейся с клиента.
Ellin пишет:
> Вобщем получается вариант с разбиением на хранимки наиболее оптимальный > по производительности?
Потенциально -- да, но там куча нюансов, связанных с кэшированием
планов процедур и работой приложения. Иногда разбивать на несколько
процедур просто нецелесообразно, потому что лучших планов всё равно
не добъёшься, а иногда -- просто необходимо.
К тому же нужно ещё знать современный MSSQL (это нюансы по кэшированию
планов), а я его знаю плохо.
> Далее идет вариант с if в одной хранимке > Далее вариант с or в условии
Вариант с OR в условии -- вообще никакой, поэтому
его лучше не использовать и не рассматривать,
если таблица хоть сколько-нибудь велика и
запрос нужен быстрым.
> WHERE > (CASE WHEN @Id <> 0 THEN pc.Id ELSE 1 END)= > (CASE WHEN @Id <> 0 THEN @Id ELSE 1 END)
А это всё равно , с CASE или c OR. C CASE даже наверное
ещё и хуже.
> Оцените его плз... Как по производительности? Насколько так принято писать?
Производительность -то не оценить, но потенциально ты таким образом
отсекаешь у оптимизатора возможность сделать хороший план запроса.
А дальше -- от запроса зависит. Если хороший план запроса этому
запросу вообще нужен (есть такие запросы, которым не нужнен), то потенциально
производительность с такими WHERE, где такие OR-ы (именно такие, а не
произвольные OR-ы), где выражения с использованием колонок, а не прямое
сравнение их со значниями, будет ниже.
sunshine пишет: > Ну уж я не знаю, как сильно должно прижать с производительностью, чтобы > на разные хранимки это разбивать, с вытекающим отсюда дублированием кода > (если я правильно понял Вашу мысль)...
Правильно, правильно. Главное, что нужно понять, что при программировании
на SQL такие вещи, как повторное использование кода, читаемость кода и
вообще многое из того, что принято считать хорошим тоном при программировании
на обычных императивных языках программирования общего назначения, не
являются главными. Они хороши, только если не мешают главному -- достижению
высокой производительности запросов.
Нужно написать хранимку, которая выбирает данные селектом с идентификатором равным входному параметру. Если идентификатор равен 0, то нужно возвращать все записи. Как в таких случаях писать. Мне почему то подход в стиле:
IF (@Type IS NOT NULL)
BEGIN
SELECT
DefProcID,
...
WHERE
...
AND TCLS.ClsTypeID = @Type
END
ELSE
BEGIN
SELECT
DefProcID,
...
WHERE ...
END
Здравствуйте, MasterZiv, Вы писали:
MZ>А зря он тебе не нравится. Наоборот, это -- хороший MZ>подход. Потому что писать сложные условия в одном MZ>запросе -- только путать оптимизатор. Делают MZ>даже ещё "кривее" с твоей точки зрения -- пишут MZ>эти два запроса в разных процедурах, которые MZ>возможно вызываются по аналогичному условию(ям) из одной главной, MZ>зовущейся с клиента.
Вот как раз разбить на хранимки мне, почемуто не кажется самым кривым способом...
Вобщем получается вариант с разбиением на хранимки наиболее оптимальный по производительности?
Далее идет вариант с if в одной хранимке
Далее вариант с or в условии
Так получается?
А как насчет варианта с CASE?
WHERE
(CASE WHEN @Id <> 0 THEN pc.Id ELSE 1 END)=
(CASE WHEN @Id <> 0 THEN @Id ELSE 1 END)
Оцените его плз... Как по производительности? Насколько так принято писать?
Здравствуйте, MasterZiv, Вы писали:
MZ>даже ещё "кривее" с твоей точки зрения -- пишут MZ>эти два запроса в разных процедурах, которые MZ>возможно вызываются по аналогичному условию(ям) из одной главной, MZ>зовущейся с клиента.
Ну уж я не знаю, как сильно должно прижать с производительностью, чтобы на разные хранимки это разбивать, с вытекающим отсюда дублированием кода (если я правильно понял Вашу мысль)...