Ведут ли себя подобным образом механизмы баз данных, отличные от SQL Server?
-
05-10-2019 - |
Вопрос
У меня есть хранимая процедура, которая выглядит примерно так (псевдокод)
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
select * from SOME_VIEW order by somecolumn
end
else if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
end
Все работало хорошо долгое время.Внезапно запрос начал выполняться вечно, если параметр 4 был равен «Y».Изменение кода на это:
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
set param2 = null
set param3 = null
end
if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
И он снова работает в пределах ожидаемых параметров (15 секунд или около того для более чем 40 000 записей).Это с SQL Server 2005.Суть моего вопроса заключается в этой конкретной «функции», специфичной для SQL Server, или это общая особенность среди СУРБД в целом:
- Запросы, которые работали нормально в течение двух лет, просто перестают работать по мере роста данных.
- «Новый» план выполнения лишает сервер базы данных возможности выполнять запрос, хотя логически эквивалентная альтернатива работает нормально?
Это может показаться напыщенной речью в адрес SQL Server, и я полагаю, что в некоторой степени это так, но мне действительно хочется знать, сталкиваются ли другие с подобной реальностью с Oracle, DB2 или любой другой СУБД.Хотя у меня есть некоторый опыт работы с другими, я видел такой объем и сложность только на SQL Server, поэтому мне любопытно, есть ли у других людей с большими сложными базами данных аналогичный опыт работы с другими продуктами.
Решение
Может быть несколько причин
1) актуальна ли статистика?
2) вы можете страдать от перехвата параметров
Кстати, для такого рода вещей
где (param2 имеет значение null или param2 = SOME_VIEW.Somecolumn2)
Взгляни на Используете ли вы Column=@Param ИЛИ @Param IS NULL в предложении WHERE?Не надо, это не работает
Другие советы
Я предполагаю, что это конкретный случай проблемы, и все условия, которые приводят к этому, специфичны для SQL-сервера - возможно, даже для его редакции.(Например.SQL Server 2008 будет вести себя иначе.)
Но это общая «особенность» оптимизаторов запросов.Они смотрят на ваш запрос и пытаются сделать обоснованное предположение о том, что будет выполнено быстрее всего.Как пользователи, у нас мало прямого контроля над тем, выбирает ли оптимизатор (скажем) сканирование по индексу или поиск по индексу, но мы можем влиять на это косвенно, предоставляя альтернативные способы выражения того же самого, чтобы увидеть, приведет ли это к сокращению времени выполнения.
Если других изменений схемы, которые могли бы повлиять на запрос, не было, проверьте, обновляется ли статистика индекса.Для этого мы используем еженедельное пакетное задание.