Я объединяю небольшую таблицу (1000 строк) с большой таблицей (8 миллионов строк) в SQL Server 2008. Объединение использует некластеризованный покрывающий индекс для большой таблицы, и объединение может создать три возможных плана запросов. Я пытаюсь выяснить, какой план лучше, но я также хочу обобщить эти знания, чтобы в следующий раз я мог лучше знать, какую эвристику использовать при просмотре статистики ввода-вывода SQL.
План № 1 является циклическим соединением и генерирует статистику для большой таблицы следующим образом:
Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052
План № 2 является объединением слиянием и генерирует такую статистику:
Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004
План № 3 является хеш-соединением и генерирует такую статистику:
Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010
Индекс покрытия упорядочен по (ID, Date)
. Запрос возвращает данные для примерно 50% идентификаторов и для каждого идентификатора возвращает непрерывный фрагмент данных за последние 3 месяца, который обычно составляет около 1/4 или строки для каждого идентификатора. Запрос возвращает около 1/8 от общего числа строк в индексе. Другими словами, запрос является редким, но последовательным.
Я предполагаю, что план № 1 ужасен для этой рабочей нагрузки, потому что перемещение головки диска в 2500 раз (или даже в 1041 раз) намного дороже, чем последовательное сканирование диска. Я также предполагаю, что # 3 и # 2 имеют схожие, последовательные (и, следовательно, более эффективные) шаблоны ввода / вывода.
Но есть ли случай, когда план № 1 действительно лучший, где «лучший» означает меньшее влияние на подсистему ввода-вывода и меньшее влияние на другие запросы, выполняемые одновременно?
Или это действительно зависит от многих переменных, таких как тип дисковой подсистемы, фрагментация индекса и т. Д. Если «это зависит», есть ли какие-то практические правила для решения проблемы?
источник
Ответы:
Вот ужасная сделка: в январе она стоила 12 тысяч долларов, чтобы купить 864 * ГБ * оперативной памяти . Вы можете получить большую отдачу, просто увеличив объем ОЗУ вашего сервера до такой степени, что вы никогда не столкнетесь с физическим чтением (конечно, после прогрева).
Кроме этого, действительно трудно дать чёрное или белое мнение о любом из этих данных, которые вы представляете. Конечно, в плане № 1 было больше физических чтений, но уверены ли вы, что все тесты были выполнены в аналогично подогретом кеше? Может ли быть так, что # 1 согрел кеш для # 2, какова ваша методология тестирования, чтобы гарантировать, что все случаи рассматриваются на ровном месте? Тем не менее, если вы раскошелитесь на 500 долларов и удвоите объем оперативной памяти, это будет иметь значение? # 1 имеет наименьшее логическое чтение ...
Но тогда # 2, вероятно, выиграет от высокого DOP (что одно сканирование может быть параллельным). Является ли время настенных часов № 2 лучше, чем № 1 после того, как вы добавили достаточно оперативной памяти?
Сколько из этих планов выполняется параллельно? Существуют ли десятки запросов, одновременно запрашивающих значительное предоставление памяти для хэша # 3 и, таким образом, создающих конфликт для RESOURCE_SEMAPHORE? # 2 выполняет сортировку, а также запрашивает предоставление памяти? Будет ли № 1 работать лучше, поскольку он не требует гранта (по крайней мере, из информации, размещенной ...)?
Это действительно действительно относительно, и вопрос, который вы задаете, больше похож на поиск одного решения для сложной системы уравнений ... просто может быть больше, чем одно решение.
Одно можно сказать наверняка: 8M рядов должны уместиться в оперативной памяти, и у вас должно быть достаточно места. Эти физические чтения требуют некоторых банков памяти.
источник
Для этого, казалось бы, очень простого запроса оптимизатор будет последовательно составлять лучший план в соответствии со своей моделью затрат. Стоимость модели довольно точная. Поэтому я рекомендую оставить выбор на SQL Server.
Вторая рекомендация: измерьте длительность запроса для всех трех вариантов с помощью горячего кэша. Тогда решай. (Не принимайте решение на основе операций чтения и сканирования и тому подобного. Для вас важна продолжительность.)
В общем, для выбора наилучшего типа соединения (или индексов) требуется понимание того, как работают алгоритмы соединения. Это слишком много информации, чтобы размещать здесь.
источник
Игнорировать счетчик сканирования, это не важно. Сосредоточьтесь на том, как снизить логическое чтение. Основано на http://www.practicalsqldba.com/2013/07/sql-server-performance-tuning.html .
источник