Устранение неполадок с запросом, показывающим значительную разницу в производительности между двумя серверами
Применяется к: 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) или Azure Data Studio, выполните его с помощью команды 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: привязанный к ЦП (средство выполнения)
Если время ЦП близко, равно или больше затраченного времени, его можно рассматривать как запрос, связанный с ЦП. Например, если затраченное время составляет 3000 миллисекунда (мс), а время ЦП — 2900 мс, это означает, что большая часть затраченного времени тратится на ЦП. Затем можно сказать, что это запрос, привязанный к ЦП.
Примеры выполнения запросов (привязанных к ЦП):
Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|
3200 | 3000 | 300000 |
1080 | 1000 | 20 |
Логические операции чтения — чтение страниц данных и индексов в кэше — чаще всего являются драйверами использования ЦП в SQL Server. Могут быть сценарии, в которых использование ЦП происходит из других источников: цикл while (в T-SQL или другом коде, например XProcs или объектах SQL CRL). Второй пример в таблице иллюстрирует такой сценарий, в котором большая часть ЦП не является результатом операций чтения.
Примечание.
Если время ЦП больше длительности, это означает, что выполняется параллельный запрос; несколько потоков используют ЦП одновременно. Дополнительные сведения см. в разделе Параллельные запросы — средство выполнения или официант.
Тип 2: ожидание на узком месте (официант)
Запрос ожидает узкого места, если затраченное время значительно больше времени ЦП. Затраченное время включает время выполнения запроса на ЦП (время ЦП) и время ожидания освобождения ресурса (время ожидания). Например, если затраченное время составляет 2000 мс, а время ЦП — 300 мс, время ожидания — 1700 мс (2000 – 300 = 1700). Дополнительные сведения см. в разделе Типы ожиданий.
Примеры ожидающих запросов:
Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|
2000 | 300 | 28000 |
10080 | 700 | 80000 |
Параллельные запросы — средство выполнения или официант
Параллельные запросы могут использовать больше времени ЦП, чем общая длительность. Цель параллелизма — разрешить нескольким потокам одновременно выполнять части запроса. За одну секунду часов запрос может использовать восемь секунд времени ЦП, выполнив восемь параллельных потоков. Поэтому становится сложно определить привязанный к ЦП или ожидающий запрос на основе затраченного времени и разницы во времени ЦП. Однако, как правило, следуйте принципам, перечисленным в двух разделах выше. Сводка:
- Если затраченное время гораздо больше времени ЦП, считайте его официантом.
- Если время ЦП гораздо больше, чем затраченное время, считайте его средствами выполнения.
Примеры параллельных запросов:
Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|
1200 | 8100 | 850000 |
3080 | 12300 | 1500000 |
Шаг 3. Сравнение данных с обоих серверов, выяснение сценария и устранение проблемы
Предположим, что есть два компьютера с именами Server1 и Server2. При этом запрос выполняется медленнее на Сервере1, чем на Сервере 2. Сравните время с обоих серверов, а затем следуйте действиям сценария, который лучше всего соответствует вашему из следующих разделов.
Сценарий 1. Запрос на сервере Server1 использует больше времени ЦП, а логические операции чтения на сервере Server1 выше, чем на Сервере 2
Если время ЦП на сервере Server1 гораздо больше, чем на Сервере2, а затраченное время совпадает с временем ЦП на обоих серверах, основные ожидания или узкие места отсутствуют. Увеличение времени ЦП на Сервере Server1, скорее всего, вызвано увеличением логических операций чтения. Значительное изменение логических операций чтения обычно указывает на разницу в планах запросов. Например:
Сервер | Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|---|
Server1 | 3100 | 3000 | 300000 |
Server2 | 1100 | 1000 | 90200 |
Действие: проверка планов выполнения и сред
- Сравните планы выполнения запроса на обоих серверах. Для этого используйте один из двух методов:
- Визуальное сравнение планов выполнения. Дополнительные сведения см. в разделе Отображение фактического плана выполнения.
- Сохраните планы выполнения и сравните их с помощью функции сравнения планов SQL Server Management Studio.
- Сравнение сред. Различные среды могут привести к различиям в плане запросов или прямым различиям в использовании ЦП. К средам относятся версии сервера, параметры конфигурации базы данных или сервера, флаги трассировки, количество ЦП или тактовая частота, а также виртуальная машина и физическая машина. Дополнительные сведения см. в статье Диагностика различий в плане запросов .
Сценарий 2. Запрос является официантом на сервере Server1, но не на сервере Server2
Если время ЦП для запроса на обоих серверах одинаково, но затраченное время на Сервере Server1 гораздо больше, чем на Сервере2, запрос на Server1 тратит гораздо больше времени на ожидание узкого места. Например:
Сервер | Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|---|
Server1 | 4500 | 1000 | 90200 |
Server2 | 1100 | 1000 | 90200 |
- Время ожидания на сервере Server1: 4500 – 1000 = 3500 мс
- Время ожидания на Сервере 2: 1100 – 1000 = 100 мс
Действие: проверка типов ожидания на сервере Server1
Определите и устраните узкое место на Сервере Server1. Примерами ожиданий являются блокировка (ожидание блокировки), ожиданий блокировки, ожиданий ввода-вывода на диске, ожиданий сети и ожиданий памяти. Чтобы устранить распространенные проблемы с узким местом, перейдите к разделу Диагностика ожиданий или узких мест.
Сценарий 3. Запросы на обоих серверах являются официантами, но типы или время ожидания различаются
Например:
Сервер | Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|---|
Server1 | 8000 | 1000 | 90200 |
Server2 | 3000 | 1000 | 90200 |
- Время ожидания на сервере Server1: 8000 – 1000 = 7000 мс
- Время ожидания на Сервере 2: 3000 – 1000 = 2000 мс
В этом случае время использования ЦП на обоих серверах одинаково, что указывает на то, что планы запросов, скорее всего, одинаковы. Запросы будут выполняться одинаково на обоих серверах, если они не дождутся узких мест. Таким образом, разница в продолжительности возникает из-за разного количества времени ожидания. Например, запрос ожидает блокировки на сервере Server1 в течение 7000 мс, а при вводе-выводе на Сервере2 — 2000 мс.
Действие: проверка типов ожидания на обоих серверах
Устраняйте каждое узкое место ожидания по отдельности на каждом сервере и ускоряйте выполнение на обоих серверах. Устранение этой проблемы является трудоемким, так как необходимо устранить узкие места на обоих серверах и сделать производительность сравнимой. Чтобы устранить распространенные проблемы с узким местом, перейдите к разделу Диагностика ожиданий или узких мест.
Сценарий 4. Запрос на сервере Server1 использует больше времени ЦП, чем на сервере Server2, но логические операции чтения близки
Например:
Сервер | Затраченное время (мс) | Время ЦП (мс) | Чтение (логическое) |
---|---|---|---|
Server1 | 3000 | 3000 | 90200 |
Server2 | 1000 | 1000 | 90200 |
Если данные соответствуют следующим условиям:
- Время ЦП на Сервере Server1 намного больше, чем на Сервере 2.
- Затраченное время точно соответствует времени ЦП на каждом сервере, что указывает на отсутствие ожиданий.
- Логические операции чтения, как правило, самый высокий драйвер времени ЦП, одинаковы на обоих серверах.
Затем дополнительное время ЦП приходится на некоторые другие действия, связанные с ЦП. Этот сценарий является самым редким из всех сценариев.
Причины: трассировка, определяемые пользователем функции и интеграция со средой CLR
Эта проблема может быть вызвана следующими причинами:
- Трассировка XEvents/SQL Server, особенно с фильтрацией по текстовым столбцам (имя базы данных, имя входа, текст запроса и т. д.). Если трассировка включена на одном сервере, но не на другом, это может быть причиной разницы.
- Определяемые пользователем функции (UDF) или другой код T-SQL, выполняющий операции, привязанные к ЦП. Обычно это происходит, когда другие условия на серверах Server1 и Server2 отличаются, например размер данных, тактовая частота ЦП или план питания.
- SQL Server интеграции со средой CLR или расширенных хранимых процедур (XPs), которые могут управлять ЦП, но не выполняют логические операции чтения. Различия в библиотеках DLL могут привести к разному времени ЦП.
- Разница в SQL Server функциональных возможностей, привязанных к ЦП (например, в коде обработки строк).
Действие: проверка трассировок и запросов
Проверьте трассировку на обоих серверах на наличие следующих данных:
- Если трассировка включена на сервере Server1, но не на Сервере 2.
- Если какая-либо трассировка включена, отключите трассировку и снова запустите запрос на сервере Server1.
- Если запрос выполняется быстрее на этот раз, включите трассировку обратно, но удалите из него текстовые фильтры, если таковые имеются.
Проверьте, использует ли запрос определяемые пользователем функции, которые выполняют манипуляции со строками или выполняют обширную обработку столбцов данных в списке
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_*)
- Общие сведения и устранение проблем с блокировкой базы данных Azure SQL
- Устранение неполадок с низкой производительностью SQL Server, вызванной проблемами ввода-вывода (PAGEIOLATCH_*, WRITELOG, IO_COMPLETION, BACKUPIO)
- Разрешение конфликтов по вставке последней страницы PAGELATCH_EX в SQL Server
- Объяснения и решения, предоставляемые памятью (RESOURCE_SEMAPHORE)
- Устранение неполадок с медленными запросами, возникающими в результате ASYNC_NETWORK_IO типа ожидания
- Устранение неполадок с типом ожидания высокого HADR_SYNC_COMMIT в группах доступности Always On
- Как это работает: CMEMTHREAD и отладка
- Обеспечение того, чтобы параллелизм ждал действия (CXPACKET и CXCONSUMER)
- ОЖИДАНИЕ THREADPOOL
Описание многих типов ожиданий и то, что они указывают, см. в таблице Типы ожиданий.
Диагностика различий в планах запросов
Ниже приведены некоторые распространенные причины различий в планах запросов.
Различия в размерах данных или значениях данных
Используется ли одна база данных на обоих серверах с одной и той же резервной копией базы данных? Были ли изменены данные на одном сервере по сравнению с другим? Различия в данных могут привести к разным планам запросов. Например, соединение таблицы T1 (1000 строк) с таблицей T2 (2 000 000 строк) отличается от объединения таблицы T1 (100 строк) с таблицей T2 (2 000 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 модели обслуживания 4199 оптимизатора запросов.
Чтобы получить состояние исправлений оптимизатора запросов, выполните следующий запрос:
-- 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 Options.
Различия в подсказках запросов
Использует ли один запрос указания запросов, а другой нет? Проверьте текст запроса вручную, чтобы установить наличие указаний запроса.
Планы с учетом параметров (проблема с учетом параметров)
Вы тестируете запрос с теми же значениями параметров? Если нет, то вы можете начать с этого. Был ли план ранее скомпилирован на одном сервере на основе другого значения параметра? Протестируйте два запроса с помощью указания запроса RECOMPILE, чтобы убедиться, что повторное использование плана не выполняется. Дополнительные сведения см. в статье Исследование и устранение проблем с учетом параметров.
Различные параметры базы данных и параметры конфигурации с заданной областью
Используются ли одни и те же параметры базы данных или параметры конфигурации с областью действия на обоих серверах? Некоторые параметры базы данных могут повлиять на выбор плана. Например, совместимость баз данных, устаревшая CE и CE по умолчанию, а также sniffing. Выполните следующий запрос с одного сервера, чтобы сравнить параметры базы данных, используемые на двух серверах:
-- 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
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по