Задача, как обычно, простая: есть некая база с данными платежей, нужно из неё собирать всяческие отчеты. Особенность - в таблице с собственно проводками хранится не вся информация а ссылки на справочники. Возникает вопрос: как обеспечить максимальную производительность запроса?
Цифры приводить не буду, ибо лень, но тенденции примерно таковы:
- можно строить запросы в лоб, подключая справочники и ставя условия
- можно сперва максимально сократить выборку, отобрав нужные записи в иную таблицу, обработав их насколько возможно, а потом подключить join-ом нужные справочники.
В теории, второй вариант должен работать быстрее, за счет сокращения расходов на на поиск по справочникам. Но есть тут один нюанс: в какую таблицу отбирать. Понятно, что это должна быть либо временная таблица, либо табличная переменная, но что из них работает быстрее?
Ладно, ставлю эксперимент: отбор сперва во временную таблицу, потом в табличную переменную, с последующим суммированием. Результаты примерно одинаковы. Ну, по идее так и должно быть, и та и другая по сути просто таблицы в Tempdb (ну да, табличная переменная находится преимущественно в оперативке и сбрасывается в Tempdb если её не жватает).
Хорошо, повторим эксперимент, но к таблицам присоединим справочники. А вот тут то и вылезает различие во всей красе. После join-на справочников расчет по табличной переменной идет в РАЗЫ медленнее, чем по временной таблице. И чем больше выборка, тем этих разов больше.
Вывод: для больших объёмов, а тем более если будут использоваться join-ы, табличные переменные просто противопоказаны.
З.Ы. Проверено на 2008 и 2012 SQL сервере.
Цифры приводить не буду, ибо лень, но тенденции примерно таковы:
- можно строить запросы в лоб, подключая справочники и ставя условия
- можно сперва максимально сократить выборку, отобрав нужные записи в иную таблицу, обработав их насколько возможно, а потом подключить join-ом нужные справочники.
В теории, второй вариант должен работать быстрее, за счет сокращения расходов на на поиск по справочникам. Но есть тут один нюанс: в какую таблицу отбирать. Понятно, что это должна быть либо временная таблица, либо табличная переменная, но что из них работает быстрее?
Ладно, ставлю эксперимент: отбор сперва во временную таблицу, потом в табличную переменную, с последующим суммированием. Результаты примерно одинаковы. Ну, по идее так и должно быть, и та и другая по сути просто таблицы в Tempdb (ну да, табличная переменная находится преимущественно в оперативке и сбрасывается в Tempdb если её не жватает).
Хорошо, повторим эксперимент, но к таблицам присоединим справочники. А вот тут то и вылезает различие во всей красе. После join-на справочников расчет по табличной переменной идет в РАЗЫ медленнее, чем по временной таблице. И чем больше выборка, тем этих разов больше.
Вывод: для больших объёмов, а тем более если будут использоваться join-ы, табличные переменные просто противопоказаны.
З.Ы. Проверено на 2008 и 2012 SQL сервере.
В целом вывод верный.
ОтветитьУдалитьНо для описанного вами случая не нужны временные таблицы. Если запрос составлен корректно, то оптимизатор запросов sql-сервера сам построит план, подобный вашему алгоритму - а именно сначала произведет фильтрацию, а потом присоединение справочников, если, конечно, у вас нет фильтров по полям справочников.
Впрочем, возможно вы не полностью описали задачу.
впрочем, возможно