Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Применяется к: SQL Server
В этой статье приведены действия по устранению неполадок с производительностью, когда запрос выполняется медленнее на одном сервере, чем на другом сервере.
Симптомы
Предположим, что установлены два сервера с установленным SQL Server. Один из экземпляров SQL Server содержит копию базы данных в другом экземпляре SQL Server. При выполнении запроса к базам данных на обоих серверах запрос выполняется медленнее на одном сервере, чем на другом.
Следующие действия помогут устранить эту проблему.
Шаг 1. Определение распространенных проблем с несколькими запросами
Используйте один из следующих двух методов для сравнения производительности для двух или нескольких запросов на двух серверах:
Вручную протестируйте запросы на обоих серверах:
- Выберите несколько запросов для тестирования, особое внимание уделите запросам, которые:
- Значительно быстрее на одном сервере, чем на другом.
- Важно для пользователя или приложения.
- Часто используется или предназначено для воспроизведения проблемы по требованию.
- Достаточно долго для записи данных в нем (например, вместо запроса в 5 миллисекунд, выберите запрос на 10 секунд).
- Запустите запросы на двух серверах.
- Сравните истекшее время (длительность) на двух серверах для каждого запроса.
- Выберите несколько запросов для тестирования, особое внимание уделите запросам, которые:
Анализ данных производительности с помощью SQL Nexus.
- Сбор данных PSSDiag/SQLdiag или SQL LogScout для запросов на двух серверах.
- Импортируйте собранные файлы данных с помощью Sql Nexus и сравнивайте запросы с двух серверов. Дополнительные сведения см. в разделе "Сравнение производительности" между двумя коллекциями журналов (например, медленный и быстрый).
Сценарий 1. Только один запрос выполняется по-разному на двух серверах
Если только один запрос выполняется по-разному, проблема, скорее всего, относится к отдельному запросу, а не к среде. В этом случае перейдите к шагу 2. Сбор данных и определение типа проблемы с производительностью.
Сценарий 2. Несколько запросов выполняются по-разному на двух серверах
Если несколько запросов выполняются медленнее на одном сервере, чем другой, наиболее вероятной причиной являются различия в сервере или среде данных. Перейдите к разделу "Диагностика различий в среде" и убедитесь, что сравнение между двумя серверами является допустимым.
Шаг 2. Сбор данных и определение типа проблемы с производительностью
Сбор затраченного времени, времени ЦП и логических чтений
Чтобы собрать истекшее время и время ЦП запроса на обоих серверах, используйте один из следующих методов, наиболее подходящих для вашей ситуации:
Для текущих инструкций проверьте total_elapsed_time и cpu_time столбцы в sys.dm_exec_requests. Выполните следующий запрос, чтобы получить данные:
SELECT req.session_id , req.total_elapsed_time AS duration_ms , req.cpu_time AS cpu_time_ms , req.total_elapsed_time - req.cpu_time AS wait_time , req.logical_reads , SUBSTRING (REPLACE (REPLACE (SUBSTRING (ST.text, (req.statement_start_offset/2) + 1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(ST.text) ELSE req.statement_end_offset END - req.statement_start_offset)/2) + 1) , CHAR(10), ' '), CHAR(13), ' '), 1, 512) AS statement_text FROM sys.dm_exec_requests AS req CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS ST ORDER BY total_elapsed_time DESC;Для прошлых выполнений запроса проверьте столбцы last_elapsed_time и last_worker_time в sys.dm_exec_query_stats. Выполните следующий запрос, чтобы получить данные:
SELECT t.text, (qs.total_elapsed_time/1000) / qs.execution_count AS avg_elapsed_time, (qs.total_worker_time/1000) / qs.execution_count AS avg_cpu_time, ((qs.total_elapsed_time/1000) / qs.execution_count ) - ((qs.total_worker_time/1000) / qs.execution_count) AS avg_wait_time, qs.total_logical_reads / qs.execution_count AS avg_logical_reads, qs.total_logical_writes / qs.execution_count AS avg_writes, (qs.total_elapsed_time/1000) AS cumulative_elapsed_time_all_executions FROM sys.dm_exec_query_stats qs CROSS apply sys.Dm_exec_sql_text (sql_handle) t WHERE t.text like '<Your Query>%' -- Replace <Your Query> with your query or the beginning part of your query. The special chars like '[','_','%','^' in the query should be escaped. ORDER BY (qs.total_elapsed_time / qs.execution_count) DESCПримечание.
Если
avg_wait_timeотображается отрицательное значение, это параллельный запрос.Если вы можете выполнить запрос по запросу в SQL Server Management Studio (SSMS), sqlcmd или расширение MSSQL для Visual Studio Code, запустите его с помощью SET STATISTICS TIME
ONи SET STATISTICS IOON.SET STATISTICS TIME ON SET STATISTICS IO ON <YourQuery> SET STATISTICS IO OFF SET STATISTICS TIME OFFЗатем из сообщений вы увидите время ЦП, истекшее время и логические операции чтения, как показано ниже:
Table 'tblTest'. Scan count 1, logical reads 3, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0. SQL Server Execution Times: CPU time = 460 ms, elapsed time = 470 ms.Если вы можете собрать план запроса, проверьте данные из свойств плана выполнения.
Запустите запрос с включенной опцией Фактический план выполнения.
Выберите левый оператор из плана выполнения.
В разделе Свойства раскройте пункт QueryTimeStats.
Проверьте elapsedTime и CpuTime.
Сравните истекшее время и время ЦП запроса, чтобы определить тип проблемы для обоих серверов.
Тип 1: привязка ЦП (runner)
Если время ЦП близко, равно или выше, чем истекшее время, его можно рассматривать как запрос, привязанный к ЦП. Например, если истекшее время составляет 3000 миллисекунд (мс), а время ЦП равно 2900 мс, это означает, что большая часть истекшего времени тратится на ЦП. Затем можно сказать, что это запрос, привязанный к ЦП.
Примеры выполнения запросов с привязкой к ЦП:
| Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|
| 3200 | 3000 | 300 000 |
| 1080 | 1000 | 20 |
Логические операции чтения — чтение страниц данных и индексов в кэше — чаще всего являются драйверами использования ЦП в SQL Server. В некоторых случаях использование ЦП происходит из других источников: цикл while (в T-SQL или другом коде, таком как XProcs или объекты SQL CLR). Второй пример в таблице иллюстрирует такой сценарий, когда большинство загрузки ЦП не связано с операциями чтения.
Примечание.
Если время ЦП больше длительности, это означает, что выполняется параллельный запрос; Одновременно используется несколько потоков ЦП. Дополнительные сведения см. в разделе Параллельные запросы — исполнитель или ожидатель.
Тип 2. Ожидание узких мест (официант)
Запрос ожидает на узкое место, если истекшее время значительно превышает время работы ЦП. Истекшее время включает время выполнения запроса на ЦП (время ЦП) и время ожидания освобождения ресурса (время ожидания). Например, если истекшее время составляет 2000 мс, а время ЦП составляет 300 мс, время ожидания составляет 1700 мс (2000 – 300 = 1700). Дополнительные сведения см. в разделе "Типы ожиданий".
Примеры ожидающих запросов:
| Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|
| 2000 | 300 | 28000 |
| 10 080 | 700 | 80 000 |
Параллельные запросы — исполнитель или ожидатель
Параллельные запросы могут затрачивать больше времени процессора, чем общая длительность. Цель параллелизма — разрешить нескольким потокам одновременно выполнять части запроса. В течение одной секунды времени запрос может использовать восемь секунд времени ЦП, выполнив восемь параллельных потоков. Таким образом, становится сложно определить привязанный к ЦП или ожидающий запрос на основе истекшего времени и разницы времени ЦП. Однако в качестве общего правила следуйте принципам, перечисленным в приведенных выше двух разделах. Сводка:
- Если истекшее время значительно превышает время ЦП, считайте это ожиданием.
- Если время ЦП значительно больше, чем время выполнения, рассмотрите это как процесс.
Примеры параллельных запросов:
| Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|
| 1200 | 8100 | 850000 |
| 3080 | 12300 | 1 500 000 |
Шаг 3. Сравнение данных с обоих серверов, определение сценария и устранение неполадок
Предположим, что существует два компьютера с именем Server1 и Server2. Запрос выполняется медленнее на сервере 1, чем на сервере Server2. Сравните время с обоих серверов, а затем следуйте действиям сценария, который лучше всего соответствует вашим параметрам из следующих разделов.
Сценарий 1. Запрос на сервере1 использует больше времени ЦП, а логические операции чтения выше на Сервере1, чем на Сервере2.
Если время ЦП на Server1 значительно больше, чем на Server2, и истекшее время точно соответствует времени ЦП на обоих серверах, на обоих серверах нет крупных ожиданий или узких мест. Увеличение времени ЦП на сервере 1, скорее всего, вызвано увеличением логических операций чтения. Значительное изменение логических операций чтения обычно указывает на разницу в планах запросов. Например:
| Сервер | Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|---|
| Server1 | 3100 | 3000 | 300 000 |
| Server2 | 1 100 | 1000 | 90200 |
Действие: Проверка планов выполнения и среды
- Сравните планы выполнения запроса на обоих серверах. Для этого используйте один из двух методов:
- Визуально сравнивайте планы выполнения. Дополнительные сведения см. в статье Отображение фактического плана выполнения.
- Сохраните планы выполнения и сравните их с помощью функции сравнения планов SQL Server Management Studio.
- Сравнение сред. Различные среды могут привести к различиям в плане запросов или прямым различиям в использовании ЦП. Среды включают версии сервера, параметры конфигурации базы данных или сервера, флаги трассировки, количество ЦП или тактовую частоту, а также виртуальную или физическую машину. Дополнительные сведения см. в разделе "Диагностика различий в плане запросов".
Сценарий 2. Запрос является процессом ожидания на сервере Server1, но не на сервере Server2
Если время ЦП для запроса на обоих серверах аналогично, но истекшее время на Server1 гораздо больше, чем на Сервере 2, запрос на Сервер1 тратит гораздо больше времени на ожидание узких мест. Например:
| Сервер | Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|---|
| Server1 | 4500 | 1000 | 90200 |
| Server2 | 1 100 | 1000 | 90200 |
- Время ожидания сервера 1: 4500 – 1000 = 3500 мс
- Время ожидания на Сервере 2: 1100 – 1000 = 100 мс
Действие. Проверка типов ожидания на Сервере1
Определение и устранение узких мест на сервере Server1. Примеры ожиданий: блокирование (ожидания блокировки), ожидания защелок, ожидания ввода-вывода диска, ожидания сети и ожидания памяти. Чтобы устранить распространенные проблемы с узкими местами, перейдите к Диагностика ожиданий или узких мест.
Сценарий 3: Запросы на обоих серверах – это ожидающие процессы, но типы или время ожидания отличаются.
Например:
| Сервер | Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|---|
| Server1 | 8000 | 1000 | 90200 |
| Server2 | 3000 | 1000 | 90200 |
- Время ожидания сервера 1: 8000 – 1000 = 7000 мс
- Время ожидания на Сервере 2: 3000 – 1000 = 2000 мс
В этом случае время ЦП совпадает на обоих серверах, что означает, что планы запросов, скорее всего, одинаковы. Запросы будут выполняться одинаково на обоих серверах, если они не ожидают узких мест. Таким образом, различия длительности исходят из различных объемов времени ожидания. Например, запрос ожидает блокировки на сервере Server1 в течение 7000 мс, пока он ожидает ввода-вывода на сервере Server2 в течение 2000 мс.
Действие. Проверка типов ожидания на обоих серверах
Устраняйте каждое узкое место ожидания по отдельности на каждом сервере и ускоряйте выполнение на обоих серверах. Устранение этой проблемы является трудоемким, так как необходимо устранить узкие места на обоих серверах и сделать производительность сравнимой. Чтобы устранить распространенные проблемы с узкими местами, перейдите к разделу Диагностика ожиданий или узких мест.
Сценарий 4: Запрос на Server1 использует больше времени работы ЦП, чем на Server2, но логические чтения почти равны.
Например:
| Сервер | Истекшее время (мс) | Время ЦП (мс) | Операции чтения (логические) |
|---|---|---|---|
| Server1 | 3000 | 3000 | 90200 |
| Server2 | 1000 | 1000 | 90200 |
Если данные соответствуют следующим условиям:
- Время ЦП на Сервере1 гораздо больше, чем на Сервере 2.
- Затраченное время тесно соответствует времени обработки ЦП на всех серверах, что свидетельствует об отсутствии задержек.
- Логические операции чтения, как правило, являются наибольшим фактором использования процессора и аналогичны на обоих серверах.
Затем дополнительное время ЦП обусловлено некоторыми другими действиями, зависящими от ЦП. Этот сценарий является самым редким из всех сценариев.
Причины: трассировка, функции, определяемые пользователем (UDF) и интеграция CLR
Эта проблема может быть вызвана следующими причинами:
- Трассировка XEvents/SQL Server, в особенности с фильтрацией по текстовым столбцам (имя базы данных, имя пользователя, текст запроса и т. д.). Если трассировка включена на одном сервере, но не на другом, это может быть причиной разницы.
- Определяемые пользователем функции (UDFS) или другой код T-SQL, выполняющий операции, связанные с ЦП. Обычно это может быть причиной, когда другие условия отличаются на сервере Server1 и Server2, таких как размер данных, скорость ЦП или план питания.
- Интеграция CLR SQL Server или расширенные хранимые процедуры (XPs), которые могут влиять на загрузку ЦП, но не выполнять логические операции чтения. Различия в библиотеках DLL могут привести к разному времени ЦП.
- Разница в функциональных возможностях SQL Server, привязанных к ЦП (например, коду строковой манипуляции).
Действие: Проверка трассировок и запросов
Проверьте трассировку на обоих серверах следующим образом:
- Если на Server1 включена трассировка, но не на Server2.
- Если любая трассировка включена, отключите трассировку и снова запустите запрос на сервере Server1.
- Если запрос выполняется быстрее на этот раз, включите трассировку обратно, но удалите из него фильтры текста, если есть какие-либо.
Проверьте, использует ли запрос функции, определяемые пользователем (UDF), для манипуляций со строками или обширной обработки данных в столбцах списка
SELECT.Проверьте, содержит ли запрос циклы, рекурсии функций или вложенные элементы.
Диагностика различий среды
Проверьте следующие вопросы и определите, является ли сравнение двух серверов допустимым.
Являются ли два экземпляра SQL Server одинаковыми версиями или сборками?
В противном случае, возможно, были некоторые исправления, которые привели к различиям. Выполните следующий запрос, чтобы получить сведения о версии на обоих серверах:
SELECT @@VERSIONСовпадает ли объем физической памяти на обоих серверах?
Если на одном сервере имеется 64 ГБ памяти, а другой — 256 ГБ памяти, это было бы существенной разницей. С большим объемом памяти, доступной для кэширования страниц данных и индексов и планов запросов, запрос можно оптимизировать по-разному на основе доступности аппаратных ресурсов.
Похожи ли конфигурации оборудования, связанные с ЦП, на обоих серверах? Например:
Количество ЦП зависит от компьютеров (24 ЦП на одном компьютере и 96 ЦП на другом).
Энергопланы — сбалансированный и высокая производительность.
Виртуальная машина (ВМ) и физическая машина (на голом железе).
Hyper-V и VMware — разница в конфигурации.
Разница скорости часов (более низкая скорость часов и более высокая скорость часов). Например, 2 ГГц и 3,5 ГГц могут иметь разницу. Чтобы получить скорость часов на сервере, выполните следующую команду PowerShell:
Get-CimInstance Win32_Processor | Select-Object -Expand MaxClockSpeed
Используйте один из следующих двух способов проверки скорости ЦП серверов. Если они не создают сопоставимые результаты, проблема выходит за пределы SQL Server. Это может быть разница в плане питания, меньше ЦП, проблема программного обеспечения виртуальной машины или разница скорости часов.
Выполните следующий скрипт PowerShell на обоих серверах и сравните выходные данные.
$bf = [System.DateTime]::Now for ($i = 0; $i -le 20000000; $i++) {} $af = [System.DateTime]::Now Write-Host ($af - $bf).Milliseconds " milliseconds" Write-Host ($af - $bf).Seconds " Seconds"Выполните следующий код Transact-SQL на обоих серверах и сравните выходные данные.
SET NOCOUNT ON DECLARE @spins INT = 0 DECLARE @start_time DATETIME = GETDATE(), @time_millisecond INT WHILE (@spins < 20000000) BEGIN SET @spins = @spins +1 END SELECT @time_millisecond = DATEDIFF(millisecond, @start_time, getdate()) SELECT @spins Spins, @time_millisecond Time_ms, @spins / @time_millisecond Spins_Per_ms
Диагностика задержек или узких мест
Чтобы оптимизировать запрос, который задерживается из-за узких мест, определите, сколько длится ожидание и где находится узкое место (тип ожидания). После подтверждения типа ожидания уменьшите время ожидания или полностью исключите ожидание.
Чтобы вычислить приблизительное время ожидания, вычитайте время ЦП (рабочий период) из истекшего времени запроса. Как правило, время ЦП — это фактическое время выполнения, а оставшаяся часть времени выполнения запроса — ожидание.
Примеры вычисления приблизительной длительности ожидания:
| Истекшее время (мс) | Время ЦП (мс) | Время ожидания (мс) |
|---|---|---|
| 3200 | 3000 | 200 |
| 7080 | 1000 | 6080 |
Определение узкого места или времени ожидания
Чтобы определить исторические длительные запросы (например, >20% от общего времени ожидания), выполните следующий запрос. Этот запрос использует статистику производительности для кэшированных планов запросов с момента начала SQL Server.
SELECT t.text, qs.total_elapsed_time / qs.execution_count AS avg_elapsed_time, qs.total_worker_time / qs.execution_count AS avg_cpu_time, (qs.total_elapsed_time - qs.total_worker_time) / qs.execution_count AS avg_wait_time, qs.total_logical_reads / qs.execution_count AS avg_logical_reads, qs.total_logical_writes / qs.execution_count AS avg_writes, qs.total_elapsed_time AS cumulative_elapsed_time FROM sys.dm_exec_query_stats qs CROSS apply sys.Dm_exec_sql_text (sql_handle) t WHERE (qs.total_elapsed_time - qs.total_worker_time) / qs.total_elapsed_time > 0.2 ORDER BY qs.total_elapsed_time / qs.execution_count DESCЧтобы определить выполнение запросов с ожиданием дольше 500 мс, выполните следующий запрос:
SELECT r.session_id, r.wait_type, r.wait_time AS wait_time_ms FROM sys.dm_exec_requests r JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id WHERE wait_time > 500 AND is_user_process = 1Если вы можете собрать план запроса, проверьте WaitStats из свойств плана выполнения в SSMS:
- Запустите запрос с включением Плана фактического выполнения.
- Щелкните правой кнопкой мыши самый левый оператор на вкладке План выполнения
- Выберите "Свойства ", а затем свойство WaitStats .
- Проверьте waitTimeMs и WaitType.
Если вы знакомы с сценариями PSSDiag/SQLdiag или SQL LogScout LightPerf/GeneralPerf, рассмотрите возможность использования любого из них для сбора статистики производительности и определения ожиданий запросов на экземпляре SQL Server. Вы можете импортировать собранные файлы данных и проанализировать данные производительности с помощью SQL Nexus.
Ссылки на устранение или сокращение ожиданий
Причины и решения для каждого типа ожидания различаются. Не существует общего метода для разрешения всех типов ожидания. Ниже приведены статьи по диагностике и устранению распространенных проблем с типами ожидания.
- Понимание и устранение проблем блокировки (LCK_M_*)
- Изучение и устранение проблем с блокировкой Базы данных SQL Azure
- Устранение неполадок с медленной производительностью SQL Server, вызванных проблемами ввода-вывода (PAGEIOLATCH_*, WRITELOG, IO_COMPLETION, BACKUPIO)
- Устранение конфликта PAGELATCH_EX при вставке на последнюю страницу в SQL Server
- Память предоставляет объяснения и решения (RESOURCE_SEMAPHORE)
- Устранение неполадок с медленными запросами, возникающими из-за типа ожидания ASYNC_NETWORK_IO
- Устранение неполадок с типом ожидания высокой HADR_SYNC_COMMIT с помощью групп доступности AlwaysOn
- Как это работает: CMEMTHREAD и отладка их
- Делать ожидания параллелизма действенными (CXPACKET и CXCONSUMER)
- Ожидание THREADPOOL
Описание многих типов ожиданий и то, что они указывают, см. в таблице в разделе "Типы ожиданий".
Диагностика различий в планах выполнения запросов
Ниже приведены некоторые распространенные причины различий в планах запросов:
Различия размера данных или значений данных
Используется ли одна и та же база данных на обоих серверах с использованием одной резервной копии базы данных? Изменены ли данные на одном сервере по сравнению с другим? Различия данных могут привести к разным планам запросов. Например, присоединение таблицы T1 (1000 строк) к таблице T2 (2000 000 строк) отличается от объединения таблицы T1 (100 строк) с таблицей T2 (2000 000 строк). Тип и скорость
JOINоперации могут быть значительно разными.Различия статистики
Обновлены ли статистические данные в одной базе данных, а не на другой? Обновлены ли статистические данные с другой частотой выборки (например, 30% в сравнении с 100% полной выборки)? Убедитесь, что вы обновляете статистику на обеих сторонах с одинаковой частотой выборки.
Различия на уровне совместимости базы данных
Проверьте, отличаются ли уровни совместимости баз данных между двумя серверами. Чтобы получить уровень совместимости базы данных, выполните следующий запрос:
SELECT name, compatibility_level FROM sys.databases WHERE name = '<YourDatabase>'Различия версий сервера и сборки
Отличаются ли версии или сборки SQL Server между двумя серверами? Например, один сервер SQL Server версии 2014 и другой SQL Server версии 2016? Могут быть изменения продукта, которые могут привести к изменениям в выборе плана запроса. Убедитесь, что вы сравниваете ту же версию и сборку SQL Server.
SELECT ServerProperty('ProductVersion')Различия версий оценки кратности (CE)
Проверьте, включен ли устаревший средство оценки кратности на уровне базы данных. Дополнительные сведения о CE см. в разделе "Оценка кратности" (SQL Server).
SELECT name, value, is_value_default FROM sys.database_scoped_configurations WHERE name = 'LEGACY_CARDINALITY_ESTIMATION'Включение/отключение исправлений/патчей для оптимизатора
Если исправления оптимизатора запросов включены на одном сервере, но отключены на другом, можно создать разные планы запросов. Дополнительные сведения см. в статье о модели обслуживания оптимизатора запросов SQL Server.
Чтобы получить состояние исправлений оптимизатора запросов, выполните следующий запрос:
-- Check at server level for TF 4199 DBCC TRACESTATUS (-1) -- Check at database level USE <YourDatabase> SELECT name, value, is_value_default FROM sys.database_scoped_configurations WHERE name = 'QUERY_OPTIMIZER_HOTFIXES'Различия флагов трассировки
Некоторые флаги трассировки влияют на выбор плана запроса. Проверьте, включены ли флаги трассировки на одном сервере, но не включены на другом. Выполните следующий запрос на обоих серверах и сравните результаты:
-- Check at server level for trace flags DBCC TRACESTATUS (-1)Различия оборудования (количество ЦП, размер памяти)
Чтобы получить сведения о оборудовании, выполните следующий запрос:
SELECT cpu_count, physical_memory_kb/1024/1024 PhysicalMemory_GB FROM sys.dm_os_sys_infoРазличия оборудования в соответствии с оптимизатором запросов
Проверьте
OptimizerHardwareDependentPropertiesплана запроса и убедитесь, что различия в оборудовании считаются значительными для различных планов.WITH xmlnamespaces(DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') SELECT txt.text, t.OptHardw.value('@EstimatedAvailableMemoryGrant', 'INT') AS EstimatedAvailableMemoryGrant , t.OptHardw.value('@EstimatedPagesCached', 'INT') AS EstimatedPagesCached, t.OptHardw.value('@EstimatedAvailableDegreeOfParallelism', 'INT') AS EstimatedAvailDegreeOfParallelism, t.OptHardw.value('@MaxCompileMemory', 'INT') AS MaxCompileMemory FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp CROSS APPLY qp.query_plan.nodes('//OptimizerHardwareDependentProperties') AS t(OptHardw) CROSS APPLY sys.dm_exec_sql_text (CP.plan_handle) txt WHERE text Like '%<Part of Your Query>%'Время ожидания оптимизатора
Существует ли проблема с временем ожидания оптимизатора? Оптимизатор запросов может остановить оценку параметров плана, если выполняемый запрос слишком сложный. Когда он останавливается, он выбирает план с наименьшей стоимостью, доступной в то время. Это может привести к произвольному выбору плана на одном сервере по сравнению с другим.
Параметры SET
Некоторые параметры SET влияют на планирование, например SET ARITHABORT. Дополнительные сведения см. в разделе "Параметры SET".
Различия между подсказками запросов
Использует ли один запрос подсказки для запросов, а другой нет? Проверьте текст запроса вручную, чтобы установить наличие подсказок запроса.
Планы, зависящие от параметров (вопрос параметрического анализа)
Тестируете запрос с одинаковыми значениями параметров? Если нет, то вы можете начать там. Был ли план скомпилирован ранее на одном сервере на основе другого значения параметра? Проверьте два запроса, используя подсказку запроса RECOMPILE, чтобы убедиться, что не происходит повторного использования плана. Дополнительные сведения см. в разделе "Изучение и устранение проблем с учетом параметров".
Различные параметры базы данных/настройки конфигурации с ограниченными областями действия.
Одинаковые параметры базы данных или параметры конфигурации с областью действия, используемые на обоих серверах? Некоторые параметры базы данных могут повлиять на выбор плана. Например, совместимость баз данных, устаревшая ce и ce по умолчанию, а также снигирование параметров. Выполните следующий запрос с одного сервера, чтобы сравнить параметры базы данных, используемые на двух серверах:
-- On Server1 add a linked server to Server2 EXEC master.dbo.sp_addlinkedserver @server = N'Server2', @srvproduct=N'SQL Server' -- Run a join between the two servers to compare settings side by side SELECT s1.name AS srv1_config_name, s2.name AS srv2_config_name, s1.value_in_use AS srv1_value_in_use, s2.value_in_use AS srv2_value_in_use, Variance = CASE WHEN ISNULL(s1.value_in_use, '##') != ISNULL(s2.value_in_use,'##') THEN 'Different' ELSE '' END FROM sys.configurations s1 FULL OUTER JOIN [server2].master.sys.configurations s2 ON s1.name = s2.name SELECT s1.name AS srv1_config_name, s2.name AS srv2_config_name, s1.value srv1_value_in_use, s2.value srv2_value_in_use, s1.is_value_default, s2.is_value_default, Variance = CASE WHEN ISNULL(s1.value, '##') != ISNULL(s2.value, '##') THEN 'Different' ELSE '' END FROM sys.database_scoped_configurations s1 FULL OUTER JOIN [server2].master.sys.database_scoped_configurations s2 ON s1.name = s2.nameРуководства по планированию
Используются ли плановые указания для запросов на одном сервере, но не на другом? Выполните следующий запрос, чтобы установить различия:
SELECT * FROM sys.plan_guides