понедельник, 1 июля 2013 г.

О временных таблицах и табличных переменных в SQL SERVER

    Задача, как обычно, простая: есть некая база с данными платежей, нужно из неё собирать всяческие отчеты. Особенность - в таблице с собственно проводками хранится не вся информация а ссылки на справочники. Возникает вопрос: как обеспечить максимальную производительность запроса?

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

    Вывод: для больших объёмов, а тем более если будут использоваться join-ы, табличные переменные просто противопоказаны.

З.Ы. Проверено на 2008 и 2012 SQL сервере.

Похожие посты:

1 комментарий:

  1. В целом вывод верный.
    Но для описанного вами случая не нужны временные таблицы. Если запрос составлен корректно, то оптимизатор запросов sql-сервера сам построит план, подобный вашему алгоритму - а именно сначала произведет фильтрацию, а потом присоединение справочников, если, конечно, у вас нет фильтров по полям справочников.
    Впрочем, возможно вы не полностью описали задачу.
    впрочем, возможно

    ОтветитьУдалить