Оптимизация или удобство SQL


2 0

Сегодня оптимизировал запрос, который до моего вмешательства работал 4 часа. Проблема была в том, что в нем не правильно использовалась функция isnull. Это очень удобная функция, особенно, если использовать ее в блоке SELECT, но ее нужно аккуратно использовать в блоке WHERE.

Я оптимизировал функцию, которая получала в качестве параметра необходимый тип данных. Если переменная равна NULL, то функция должна вернуть все данные.

Чтобы проще было следить за тем, что я говорю, давайте представим себе следующий запрос:

declare @city varchar(100);
set @city = null;

select FirstName, LastName, City
from Members
where isnull(@city, City) = City

Я упростил функцию для простого запроса, чтобы проще было разбирать его. Если переменная @city равна null, то isnul(@city, City) вернет значение City для текущей строки и оно конечно же будет равно City, а значит запрос вернет содержимое всей базы. Если City установлен в какой-то город, то запрос вернет только этот город. Красиво? Да, но очень медленно.

Как показал мой пример, функция isnul не дает SQL серверу эффективно использовать индексы в этом месте. Сервер практически скаровал таблицу, а у меня были не люди в таблицы, а транзакции. Моя таблица транзакций состоит из миллиардов записей со сложными связями на другие таблицы, в том числе и на себя и запрос Server уходил в серьезные 4-х часовые раздумия. Никакие индексы не помогали.

Не используйте такую конструкцию на больших таблицах. Лучше написать:

declare @city varchar(100);
set @city = null;

select FirstName, LastName, City
from Members
where (@city = City or @city is null)

Если City не равен null, то будет так же возвращен только этот город, иначе вся таблица. Но такое банальное изменение позволило запросу, который я оптимизировал, выполняться меньше 30 минут. Подобные прикола как isnull(@city, City) = City удобны и будут работать быстро в секции SELECT, но не в WHERE. По крайней мере по моим наблюдениям.


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым


Комментарии

Олежка)

18 Ноября 2010

Очень дельный совет, на будущие нужно будет запомнить


tommi-boy

06 Сентября 2013

Как поакзывает практика использование or замедляет процесс выбора во много раз. Может попробовать использовать конструкцию
declare @city varchar(100);
set @city = '';

select FirstName, LastName, City
from Members
where @city in ('', City)

?


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне