2010-01-06 2 views
0

У меня есть запрос, который имеет очень дорогостоящую операцию INDEX SEEK в плане выполнения. Чтобы отслеживать причину, я включил IO STATISTICS и запустил ее. В разделе проблемы он дал следующую статистику:Нужна помощь в понимании статистики IO

Таблица '# TempStudents_Enrollment2 _________________________________________________________________ 000000004D5F. Количество сканирования 0, логического чтение 60, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

таблицу «Worktable». Количество сканирования 0, логического чтения 0, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица '# TempRace2 ________________________________________________________________________________ 000000004D58'. Количество сканирования 1, логическое чтение 1, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

таблицу «Worktable». Количество сканирования 0, логического чтения 0, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица 'RefRace'. Количество сканирования 120, логического чтения 240, физических чтений 1, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

таблицу 'RefFedEnctyRaceCatg'. Сканирование счетчик 18, логический читает 36, физический читает 2, упреждающего чтения читает 0, подбросить логических чтений 0, нескладный физических чтений 0, нескладный упреждающего чтения читает 0.

Table '# 43B0BA0F'. Количество сканирования 1, логического чтения 60, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица '# 42BC95D6. Количество сканирования 1, логического чтения 60, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

таблицу '# 41C8719D'. Количество сканирования 1, логического чтения 60, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

таблицу '# 40D44D64'. Количество сканирования 1, логического чтения 60, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица '# LEA2 _____________________________________________________________________________________ 000000004D56.Количество сканирования 1, логическое чтение 60, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читают 0.

Таблица '# 39332B9C. Количество сканирования 1, логического чтения 60, физических чтений 0, упреждающего чтения читает 0, нескладный логического чтения 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица '# School2 __________________________________________________________________________________ 000000004D57'. Количество сканирования 1, логическое чтение 29164, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

Таблицы '#GenderKey ________________________________________________________________________________ 000000004D5A. Количество сканирования 1, логическое чтение 29164, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

Таблицы '#LangAcqKey _______________________________________________________________________________ 000000004D5B'. Количество сканирования 1, логическое чтение 29164, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

Таблицы '#TransferCatKey ___________________________________________________________________________ 000000004D5C. Количество сканирования 1, логическое чтение 29164, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

Таблицы '#ResCatKey ________________________________________________________________________________ 000000004D5D. Количество сканирования 1, логическое чтение 29164, физических чтения 0, упреждающее чтение читает 0, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читает 0.

Таблица 'RPT_SnapShot_1_4_StuPgm_Denorm'. Сканирование подсчета 2344954, логическое чтение 4992518, физических чтения 16, упреждающее чтение читает 8, нескладехи логическим читает 0, подбросить физические читает 0, подбросить упреждающее чтение читают 0.

Таблица '# 3FE0292B. Количество сканирования 1, логического чтения 2344954, физических чтений 0, упреждающего чтения читает 0, нескладный логический читает 0, нескладный физических чтений 0, подбросить упреждающего чтения читает 0.

Таблица 'RPT_SnapShot_1_4_StuEnrlmt_Denorm'. Количества сканирования 20, логического чтение 87679, физических чтения 0, упреждающее чтение читает 87425, нескладные логические читает 0, подбросить физических чтения 0, подбросить упреждающее чтение читает 0.

Таблицы '#GradeKey _________________________________________________________________________________ 000000004D59' ,Количество сканирования 1, логического чтения 1, физических чтений 0, упреждающего чтения читает 0, нескладеха логический читает 0, подбросить физический читает 0, подбросить упреждающего чтения читает 0.

Что я должен искать в здесь, когда я хочу улучшить производительность? Линия с более чем 2 миллионами для счета сканирования выглядела подозрительной для меня, но я действительно не знаю. Кто-нибудь видит что-нибудь здесь, что я должен изучить более подробно?

+0

Было бы полезно показать структуры таблиц и образцы данных и фактический запрос. –

ответ

1

Похоже, что существует довольно дорогостоящий индекс сканирование происходит там: Table 'RPT_SnapShot_1_4_StuPgm_Denorm'. Scan count 2344954, logical reads 4992518.

+0

Я тоже так думал. Из того, что я могу сказать, этот раздел в плане выполнения возвращается как поиск индекса, который занимает очень много времени. Могут ли они быть связаны? –

+1

Это может быть поиск индекса во внутреннем объединении цикла, поэтому, если вы можете изменить его на соединение хеш-совпадения (или даже лучше - слить объединение), тогда он может пойти намного быстрее. –

+0

Я думаю, что вы можете быть правы, мой план выполнения показывает, что 27% тратится на вложенный цикл, который предшествует моей операции поиска индекса (что составляет 70%). Как мне изменить его на хеш-матч или слияние? Лучшие индексы? –

0

Единственная фигура, о которой стоит беспокоиться, это «Логическое чтение». Физические чтения будут зависеть от того, сколько данных в настоящее время кэшировано, что может меняться каждый раз, когда выполняется запрос.

Количество отсчетов иногда говорит, но на самом деле не стоит фокусироваться.

Edit: Смотрите еще некоторое обсуждение этих результатов in this post here. Что я имел в виду «говорить», что счетчик сканирования может иногда быть «флаг», указывающий, что SQL является извлечение данных из этой таблицы нерационально. Но когда дело доходит до проверки различных версий вашего запроса во время оптимизации, я уделяю гораздо больше внимания улучшению, которое я могу сделать в логических чтениях.

+0

Интересно, не могли бы вы рассказать о том, что вы имеете в виду, когда говорите, что «Количество сканирования иногда говорит ...»? –

1

Вы уже выполнили «set statistics IO on». В меню «Запрос» включите «Включить фактический план выполнения» и «Включить статистику клиентов». Запустите свой запрос/процедуру. В «сообщения« вкладка наивысшего »логическое чтение« номер, запомните эту таблицу. В закладке «Планирование выполнения» найдите таблицу, которую вы обнаружили на шаге раньше (обычно это самый высокий процент затрат, связанный с планом). Если это «« Сканирование »(сканирование таблицы или сканирование индекса), вам не хватает соответствующего индекса, или соответствующий индекс не имеет хорошей статистики. Если это «Ищи», то строки, которые вы ищете, широко разбросаны по блокам. Вы должны привести их физически вместе, создав индекс CLUSTERED на колонке, которую вы ищете. Это ОЧЕНЬ эффективный метод. Не многие люди знают, что такое кластеризованные индексы. Проведите некоторое время, изучая их. По умолчанию сервер Sql создает первичный ключ, который кластеризуется, и большинство людей оставляют его таким образом. И во многих случаях это может привести к ухудшению производительности. Вам нужен кластеризованный индекс для физической группировки строк вместе столбцами (столбцами), на которые вы создаете свой кластерный индекс. У вас может быть только один кластеризованный индекс для каждой таблицы. Кластеризованный индекс не обязательно должен быть уникальным, он не должен быть PK, может состоять из нескольких столбцов. Вы можете переписать запрос, например. заменить существует с IN и наоборот, или заменить существует с объединением таблицы. Существует не самый быстрый способ соединения. Если бы он был один, все остальные типы были бы автоматически преобразованы в самый быстрый. Это зависит от данных, доступных индексов, количества бара и т. Д.

Всегда измеряйте, не принимайте. Измерение - это только правда. Насколько вам удалось сократить логические чтения, вам удалось оптимизировать запрос. Другими оптимизациями будет уровень базы данных, выполняемый DBA (кеш памяти, параллельные процессы, система хранения, проверка событий ожидания и т. Д.).

2

Источник: MS SQL Server 2008 R2 Высвобожденная

сканирования граф Сканирование подсчитанное значение указывает на то, сколько раз соответствующая таблица была доступ во время выполнения запроса. Внешняя таблица соединения вложенного цикла обычно имеет счетчик сканирования 1. Количество сканирования для внутренних таблиц обычно отражает количество поисков таблицы , которая обычно совпадает с количеством квалификационных строк в внешний таблица. Количество логических чтений для внутренней таблицы равно числу сканирования, умноженному на на количество страниц на поиск для каждого сканирования. Обратите внимание, что подсчет сканирования для внутренней таблицы может иногда быть только 1 для вложенного соединения, если SQL Server копирует необходимые строки из внутренней таблицы в рабочую таблицу в кэш-памяти и считывает из рабочей таблицы последующие итерации (для например, если он использует операцию «Столовая катушка»). Счет сканирования для объединений хэша и объединений объединяется, как правило, 1 для обеих таблиц, участвующих в объединении, но логические чтения для этих типов объединений обычно значительно выше.

логического чтения Логический считывает значение указывает общее количество доступа к страницам необходимо обработать запрос. Каждая страница считывается из кэш-памяти, даже если ее сначала нужно прочитать с диска. Каждое физическое чтение всегда имеет соответствующее логическое чтение, поэтому число физических будет никогда не превышать количество логических чтений. Поскольку одна и та же страница может быть обращена несколько раз, количество логических чтений для таблицы может превышать количество количество страниц в таблице.

Физические данные Значение физического считывания указывает фактическое количество страниц, считанных с диска. Значение для физических чтений может сильно различаться и должно уменьшаться или уменьшаться до нуля с последующими выполнениями запроса, поскольку данные будут загружены в кеш данных первым выполнением . Количество физических чтений также будет уменьшено на страницах, внесенных в память механизмом чтения.

упреждающего чтения читает Считывание вперед считывает значение указывает число страниц, считываются в кэш-памяти, используя механизм упреждающего чтения, запрос был обработан. Страницы, прочитанные механизмом read-ahead , не обязательно будут использоваться запросом. Когда страница, прочитанная механизмом read-ahead , обращается к запросу, он считается логическим чтением, но не физическим. Механизм чтения-чтения можно рассматривать как оптимистичную форму физического ввода-вывода, страницы в кэш-памяти, которые ожидают запроса, потребуются до запроса . Когда вы сканируете таблицу или индекс, просматривается таблица распределения индекса таблицы страниц (IAM), чтобы определить, какие экстенты принадлежат объекту. Степень состоит из восьми страниц данных. Восемь страниц в объеме считываются с одним чтением, а экстенты считываются в том порядке, в котором они хранятся на диске. Если таблица распределена по нескольким файлам, механизм чтения вперед выполняет параллельное чтение из восьми файлов на времени вместо последовательного чтения из файла files.read.

Смежные вопросы