#sql-server #sql-server-2005 #stored-procedures
#sql-сервер #sql-server-2005 #хранимые процедуры
Вопрос:
В SQL Server 2005 у меня есть запрос, который включает в себя множество соединений большого размера (каждая таблица имеет порядок от нескольких тысяч строк до нескольких миллионов строк, а средние таблицы, вероятно, эквивалентны 10-15 столбцам целых чисел и datetimes.
Чтобы ускорить выполнение запроса, я подумываю о разделении одного большого запроса на хранимую процедуру, которая выполняет пару соединений, сохраняет этот результат в некоторой временной таблице, а затем соединяет эту временную таблицу с другой временной таблицей, которая также была результатом нескольких соединений.
В настоящее время я использую табличные переменные для хранения промежуточных таблиц, и с одного раза производительность заметно улучшилась. Но в рабочей среде, tempdb
похоже, возникает узкое место ввода-вывода.
Есть ли лучший способ подумать о решении такой проблемы? Я имею в виду, не слишком ли далеко здесь используются табличные переменные?
Комментарии:
1. Можете ли вы предоставить нам более подробную информацию о запросе? Я бы не подумал, что разделение одного запроса на основе набора на несколько временных таблиц и запросов ускорит его выполнение….
2. Как выглядит ваш план выполнения?
3. задействовано около 8 соединений. План выполнения огромен всевозможными объединениями, поиском и сканированием различных таблиц
4. можете ли вы опубликовать информацию из сканированных таблиц? Я предполагаю, что это самые дорогостоящие?
5. Если вы используете несколько соединений, которые принудительно проверяют таблицу, вы можете обнаружить, что один или два дополнительных индекса могут повысить производительность. Похоже, вы уже проверили план выполнения запроса — предполагал ли он, что какие-либо индексы отсутствуют? Вы также можете выполнить одну из моих любимых быстрых проверок отсутствия индекса или ознакомиться с некоторой общей информацией о поиске отсутствующих индексов .
Ответ №1:
Табличные переменные могут занимать довольно много памяти в базе данных TempDB.
В больших производственных средах я видел лучших программистов SQL, чем я, которые используют стандартные таблицы для этой цели; По сути, это временные таблицы, но они создают их как обычные таблицы и присваивают им специальный префикс или суффикс. Это имеет дополнительное преимущество (как и в случае с временными таблицами), заключающееся в возможности использования индексов для облегчения выполнения.
Если вы можете использовать стандартную таблицу или использовать временную таблицу, доступ к которой осуществляется на всех этапах вашего сложного выполнения, возможно, вам удастся решить проблему с памятью.
Думайте об этом как о месте для кэширования данных. Фактически, вы можете обновлять этот «кэш» при каждом запуске вашей основной хранимой процедуры, просто убедитесь, что используете соответствующие транзакции и блокировку.
Представьте альтернативу — если вы используете огромную табличную переменную в хранимой процедуре, и хранимая процедура выполняется 10 или 20 раз одновременно… возможно, эта табличная переменная больше не хранится только в памяти.