Felsök en fråga som visar betydande prestandaskillnader mellan två servrar
Gäller för: SQL Server
Den här artikeln innehåller felsökningssteg för ett prestandaproblem där en fråga körs långsammare på en server än på en annan server.
Symtom
Anta att det finns två servrar med SQL Server installerat. En av SQL Server-instanserna innehåller en kopia av en databas i den andra SQL Server-instansen. När du kör en fråga mot databaserna på båda servrarna körs frågan långsammare på den ena servern än den andra.
Följande steg kan hjälpa dig att felsöka det här problemet.
Steg 1: Avgöra om det är ett vanligt problem med flera frågor
Använd någon av följande två metoder för att jämföra prestanda för två eller flera frågor på de två servrarna:
Testa frågorna manuellt på båda servrarna:
- Välj flera frågor för testning med prioritet för frågor som är:
- Betydligt snabbare på en server än på den andra.
- Viktigt för användaren/programmet.
- Körs eller utformas ofta för att återskapa problemet på begäran.
- Tillräckligt lång tid för att samla in data på den (i stället för en fråga på 5 millisekunder väljer du en 10-sekundersfråga).
- Kör frågorna på de två servrarna.
- Jämför den förflutna tiden (varaktigheten) på två servrar för varje fråga.
- Välj flera frågor för testning med prioritet för frågor som är:
Analysera prestandadata med SQL Nexus.
- Samla in PSSDiag/SQLdiag - eller SQL LogScout-data för frågorna på de två servrarna.
- Importera de insamlade datafilerna med SQL Nexus och jämför frågorna från de två servrarna. Mer information finns i Prestandajämförelse mellan två loggsamlingar (långsam och snabb till exempel).
Scenario 1: Endast en enskild fråga fungerar annorlunda på de två servrarna
Om bara en fråga presterar annorlunda är problemet mer sannolikt specifikt för den enskilda frågan snarare än för miljön. I det här fallet går du till Steg 2: Samla in data och fastställa typen av prestandaproblem.
Scenario 2: Flera frågor fungerar annorlunda på de två servrarna
Om flera frågor körs långsammare på en server än den andra är den troligaste orsaken skillnaderna i server- eller datamiljö. Gå till Diagnostisera miljöskillnader och se om jämförelsen mellan de två servrarna är giltig.
Steg 2: Samla in data och fastställa typen av prestandaproblem
Samla in förfluten tid, CPU-tid och logiska läsningar
Om du vill samla in förfluten tid och CPU-tid för frågan på båda servrarna använder du någon av följande metoder som passar bäst för din situation:
För närvarande kör du instruktioner genom att kontrollera total_elapsed_time och cpu_time kolumner i sys.dm_exec_requests. Kör följande fråga för att hämta data:
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;
För tidigare körningar av frågan kontrollerar du last_elapsed_time och last_worker_time kolumner i sys.dm_exec_query_stats. Kör följande fråga för att hämta data:
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
Kommentar
Om
avg_wait_time
visar ett negativt värde är det en parallell fråga.Om du kan köra frågan på begäran i SQL Server Management Studio (SSMS) eller Azure Data Studio kör du den med SET STATISTICS TIME
ON
och SET STATISTICS IOON
.SET STATISTICS TIME ON SET STATISTICS IO ON <YourQuery> SET STATISTICS IO OFF SET STATISTICS TIME OFF
Sedan ser du cpu-tid, förfluten tid och logiska läsningar från Meddelanden så här:
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.
Om du kan samla in en frågeplan kontrollerar du data från egenskaperna för körningsplan.
Kör frågan med Inkludera faktisk körningsplan på.
Välj operatorn längst till vänster från Körningsplan.
Från Egenskaper expanderar du egenskapen QueryTimeStats .
Kontrollera ElapsedTime och CpuTime.
Jämför den förflutna tiden och CPU-tiden för frågan för att fastställa problemtypen för båda servrarna.
Typ 1: CPU-bunden (löpare)
Om cpu-tiden är nära, lika med eller högre än den förflutna tiden, kan du behandla den som en CPU-bunden fråga. Om den förflutna tiden till exempel är 3 000 millisekunder (ms) och CPU-tiden är 2 900 ms innebär det att större delen av den förflutna tiden spenderas på processorn. Sedan kan vi säga att det är en CPU-bunden fråga.
Exempel på frågor som körs (CPU-bundna):
Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|
3200 | 3000 | 300 000 |
1080 | 1000 | 20 |
Logiska läsningar – läsning av data-/indexsidor i cacheminnet – är oftast drivrutinerna för CPU-användning i SQL Server. Det kan finnas scenarier där CPU-användning kommer från andra källor: en while-loop (i T-SQL eller annan kod som XProcs- eller SQL CRL-objekt). Det andra exemplet i tabellen illustrerar ett sådant scenario, där majoriteten av processorn inte kommer från läsningar.
Kommentar
Om CPU-tiden är större än varaktigheten anger detta att en parallell fråga körs. flera trådar använder processorn samtidigt. Mer information finns i Parallella frågor – löpare eller servitör.
Typ 2: Väntar på en flaskhals (servitör)
En fråga väntar på en flaskhals om den förflutna tiden är betydligt större än CPU-tiden. Den förflutna tiden inkluderar tiden som kör frågan på CPU -tiden (CPU-tid) och tiden som väntar på att en resurs ska släppas (väntetid). Om den förflutna tiden till exempel är 2 000 ms och cpu-tiden är 300 ms är väntetiden 1700 ms (2 000–300 = 1 700). Mer information finns i Typer av väntetider.
Exempel på väntande frågor:
Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|
2000 | 300 | 28000 |
10080 | 700 | 80000 |
Parallella frågor – löpare eller servitör
Parallella frågor kan använda mer CPU-tid än den totala varaktigheten. Målet med parallellitet är att tillåta att flera trådar kör delar av en fråga samtidigt. Under en sekund av klocktiden kan en fråga använda åtta sekunders CPU-tid genom att köra åtta parallella trådar. Därför blir det svårt att fastställa en CPU-bunden fråga eller en väntande fråga baserat på den förflutna tids- och CPU-tidsskillnaden. Men som en allmän regel följer du de principer som anges i ovanstående två avsnitt. Sammanfattningen är:
- Om den förflutna tiden är mycket större än CPU-tiden bör du betrakta den som en servitör.
- Om CPU-tiden är mycket större än den förflutna tiden bör du betrakta den som en löpare.
Exempel på parallella frågor:
Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|
1200 | 8100 | 850000 |
3080 | 12300 | 1500000 |
Steg 3: Jämför data från båda servrarna, ta reda på scenariot och felsöka problemet
Anta att det finns två datorer med namnet Server1 och Server2. Och frågan körs långsammare på Server1 än på Server2. Jämför tiderna från båda servrarna och följ sedan åtgärderna i scenariot som bäst matchar dina från följande avsnitt.
Scenario 1: Frågan på Server1 använder mer CPU-tid och de logiska läsningarna är högre på Server1 än på Server2
Om CPU-tiden på Server1 är mycket större än på Server2 och den förflutna tiden matchar CPU-tiden nära på båda servrarna, finns det inga större väntetider eller flaskhalsar. Ökningen av CPU-tiden på Server1 orsakas troligen av en ökning av logiska läsningar. En betydande ändring i logiska läsningar indikerar vanligtvis en skillnad i frågeplaner. Till exempel:
Server | Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|---|
Server1 | 3100 | 3000 | 300 000 |
Server2 | 1100 | 1000 | 90200 |
Åtgärd: Kontrollera körningsplaner och miljöer
- Jämför körningsplaner för frågan på båda servrarna. Det gör du genom att använda någon av de två metoderna:
- Jämför körningsplaner visuellt. Mer information finns i Visa en faktisk körningsplan.
- Spara körningsplanerna och jämför dem med sql Server Management Studio-planjämförelsefunktionen.
- Jämför miljöer. Olika miljöer kan leda till frågeplansskillnader eller direkta skillnader i CPU-användning. Miljöer omfattar serverversioner, inställningar för databas- eller serverkonfiguration, spårningsflaggor, cpu-antal eller klockfrekvens samt virtuell dator jämfört med fysisk dator. Mer information finns i Diagnostisera skillnader i frågeplan.
Scenario 2: Frågan är en servitör på Server1 men inte på Server2
Om CPU-tiderna för frågan på båda servrarna är liknande, men den förflutna tiden på Server1 är mycket större än på Server2, ägnar frågan på Server1 mycket längre tid åt att vänta på en flaskhals. Till exempel:
Server | Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|---|
Server1 | 4 500 | 1000 | 90200 |
Server2 | 1100 | 1000 | 90200 |
- Väntetid på Server1: 4500–1 000 = 3 500 ms
- Väntetid på Server2: 1100–1 000 = 100 ms
Åtgärd: Kontrollera väntetyper på Server1
Identifiera och eliminera flaskhalsen på Server1. Exempel på väntetider är blockering (låsväntningar), spärrväntningar, disk-I/O-väntetider, nätverksvänte och minnesvänte. Om du vill felsöka vanliga flaskhalsproblem fortsätter du till Diagnostisera väntetider eller flaskhalsar.
Scenario 3: Frågorna på båda servrarna är servitörer, men väntetiderna är olika
Till exempel:
Server | Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|---|
Server1 | 8000 | 1000 | 90200 |
Server2 | 3000 | 1000 | 90200 |
- Väntetid på Server1: 8000–1 000 = 7 000 ms
- Väntetid på Server2: 3000–1 000 = 2 000 ms
I det här fallet är cpu-tiderna liknande på båda servrarna, vilket indikerar att frågeplaner sannolikt är desamma. Frågorna skulle fungera lika på båda servrarna om de inte väntar på flaskhalsarna. Så varaktighetsskillnaderna kommer från de olika väntetiderna. Frågan väntar till exempel på lås på Server1 på 7 000 ms medan den väntar på I/O på Server2 på 2 000 ms.
Åtgärd: Kontrollera väntetyper på båda servrarna
Åtgärda varje flaskhals väntar individuellt på varje server och påskynda körningen på båda servrarna. Felsökningen av det här problemet är arbetsintensiv eftersom du måste eliminera flaskhalsar på båda servrarna och göra prestandan jämförbar. Om du vill felsöka vanliga flaskhalsproblem fortsätter du till Diagnostisera väntetider eller flaskhalsar.
Scenario 4: Frågan på Server1 använder mer CPU-tid än på Server2, men de logiska läsningarna är nära
Till exempel:
Server | Förfluten tid (ms) | CPU-tid (ms) | Läsningar (logiska) |
---|---|---|---|
Server1 | 3000 | 3000 | 90200 |
Server2 | 1 000 | 1 000 | 90200 |
Om data matchar följande villkor:
- Cpu-tiden på Server1 är mycket större än på Server2.
- Den förflutna tiden matchar cpu-tiden nära på varje server, vilket indikerar inga väntetider.
- De logiska läsningarna, vanligtvis den högsta drivrutinen för CPU-tid, är liknande på båda servrarna.
Sedan kommer den extra CPU-tiden från vissa andra CPU-bundna aktiviteter. Det här scenariot är det mest sällsynta av alla scenarier.
Orsaker: Spårning, UDF:er och CLR-integrering
Det här problemet kan orsakas av:
- XEvents/SQL Server-spårning, särskilt med filtrering av textkolumner (databasnamn, inloggningsnamn, frågetext och så vidare). Om spårning är aktiverat på en server men inte på den andra kan detta vara orsaken till skillnaden.
- Användardefinierade funktioner (UDF:er) eller annan T-SQL-kod som utför CPU-bundna åtgärder. Detta är vanligtvis orsaken när andra villkor skiljer sig på Server1 och Server2, till exempel datastorlek, CPU-klockhastighet eller Power Plan.
- SQL Server CLR-integrering eller utökade lagrade procedurer (XPs) som kan driva CPU men inte utföra logiska läsningar. Skillnader i DLL:er kan leda till olika CPU-tider.
- Skillnad i SQL Server-funktioner som är CPU-bundna (t.ex. strängmanipuleringskod).
Åtgärd: Kontrollera spårningar och frågor
Kontrollera spårningar på båda servrarna för följande:
- Om det finns någon spårning aktiverad på Server1 men inte på Server2.
- Om någon spårning är aktiverad inaktiverar du spårningen och kör frågan igen på Server1.
- Om frågan körs snabbare den här gången aktiverar du spårningen tillbaka men tar bort textfilter från den, om det finns några.
Kontrollera om frågan använder UDF:er som utför strängmanipuleringar eller utför omfattande bearbetning av datakolumner i
SELECT
listan.Kontrollera om frågan innehåller loopar, funktionsrekursioner eller kapslingar.
Diagnostisera miljöskillnader
Kontrollera följande frågor och avgör om jämförelsen mellan de två servrarna är giltig.
Är de två SQL Server-instanserna samma version eller version?
Annars kan det finnas vissa korrigeringar som orsakade skillnaderna. Kör följande fråga för att hämta versionsinformation på båda servrarna:
SELECT @@VERSION
Liknar mängden fysiskt minne på båda servrarna?
Om en server har 64 GB minne medan den andra har 256 GB minne skulle det vara en betydande skillnad. Med mer minne tillgängligt för cachelagring av data-/indexsidor och frågeplaner kan frågan optimeras på olika sätt baserat på maskinvaruresurstillgänglighet.
Liknar processorrelaterade maskinvarukonfigurationer på båda servrarna? Till exempel:
Antalet processorer varierar mellan datorer (24 processorer på en dator jämfört med 96 processorer på den andra).
Energischeman – balanserade jämfört med höga prestanda.
Virtuell dator (VM) jämfört med fysisk dator (utan operativsystem).
Hyper-V jämfört med VMware – skillnad i konfiguration.
Skillnad i klockhastighet (lägre klockhastighet jämfört med högre klockhastighet). Till exempel kan 2 GHz jämfört med 3,5 GHz göra skillnad. Kör följande PowerShell-kommando för att hämta klockhastigheten på en server:
Get-CimInstance Win32_Processor | Select-Object -Expand MaxClockSpeed
Använd något av följande två sätt att testa processorhastigheten på servrarna. Om de inte ger jämförbara resultat ligger problemet utanför SQL Server. Det kan vara en skillnad i energischemat, färre processorer, problem med VM-programvara eller skillnad i klockhastighet.
Kör följande PowerShell-skript på båda servrarna och jämför utdata.
$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"
Kör följande Transact-SQL-kod på båda servrarna och jämför utdata.
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
Diagnostisera väntetider eller flaskhalsar
Om du vill optimera en fråga som väntar på flaskhalsar identifierar du hur lång väntetiden är och var flaskhalsen är (väntetypen). När väntetypen har bekräftats kan du minska väntetiden eller eliminera väntetiden helt.
Om du vill beräkna den ungefärliga väntetiden subtraherar du CPU-tiden (arbetstiden) från den förflutna tiden för en fråga. Cpu-tiden är vanligtvis den faktiska körningstiden och den återstående delen av frågans livslängd väntar.
Exempel på hur du beräknar ungefärlig väntetid:
Förfluten tid (ms) | CPU-tid (ms) | Väntetid (ms) |
---|---|---|
3200 | 3000 | 200 |
7080 | 1000 | 6080 |
Identifiera flaskhalsen eller vänta
Kör följande fråga för att identifiera historiska frågor som väntar länge (till exempel >20 % av den totala förflutna tiden är väntetiden). Den här frågan använder prestandastatistik för cachelagrade frågeplaner sedan SQL Server startades.
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
Kör följande fråga för att identifiera att frågor körs med längre väntetider än 500 ms:
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
Om du kan samla in en frågeplan kontrollerar du WaitStats från körningsplanens egenskaper i SSMS:
- Kör frågan med Inkludera faktisk körningsplan på.
- Högerklicka på operatorn längst till vänster på fliken Körningsplan
- Välj Egenskaper och sedan egenskapen WaitStats .
- Kontrollera WaitTimeMs och WaitType.
Om du är bekant med scenarier med PSSDiag/SQLdiag eller SQL LogScout LightPerf/GeneralPerf kan du använda någon av dem för att samla in prestandastatistik och identifiera väntande frågor på din SQL Server-instans. Du kan importera de insamlade datafilerna och analysera prestandadata med SQL Nexus.
Referenser för att eliminera eller minska väntetider
Orsakerna och lösningarna för varje väntetyp varierar. Det finns ingen allmän metod för att lösa alla väntetyper. Här följer artiklar om hur du felsöker och löser vanliga problem med väntetyp:
- Förstå och lösa blockeringsproblem (LCK_M_*)
- Förstå och lösa blockeringsproblem i Azure SQL Database
- Felsöka långsamma SQL Server-prestanda som orsakas av I/O-problem (PAGEIOLATCH_*, WRITELOG, IO_COMPLETION, BACKUPIO)
- Lös sista sidans inläggskonkurrens för PAGELATCH_EX i SQL-servern
- Minne ger förklaringar och lösningar (RESOURCE_SEMAPHORE)
- Felsöka långsamma frågor som beror på ASYNC_NETWORK_IO väntetyp
- Felsöka hög HADR_SYNC_COMMIT väntetyp med AlwaysOn-tillgänglighetsgrupper
- Så här fungerar det: CMEMTHREAD och felsökning av dem
- Att göra parallellitet väntar åtgärdsbart (CXPACKET och CXCONSUMER)
- THREADPOOL-väntan
Beskrivningar av många väntetyper och vad de anger finns i tabellen i Typer av väntetider.
Diagnostisera skillnader i frågeplan
Här följer några vanliga orsaker till skillnader i frågeplaner:
Skillnader i datastorlek eller datavärden
Används samma databas på båda servrarna – med samma databassäkerhetskopiering? Har data ändrats på en server jämfört med den andra? Dataskillnader kan leda till olika frågeplaner. Till exempel skiljer sig sammanfogning av tabell T1 (1 000 rader) med tabell T2 (2 000 000 rader) från att koppla tabell T1 (100 rader) med tabell T2 (2 000 000 rader). Åtgärdens
JOIN
typ och hastighet kan skilja sig avsevärt.Skillnader i statistik
Har statistiken uppdaterats på en databas och inte på den andra? Har statistiken uppdaterats med en annan exempelfrekvens (till exempel 30 % jämfört med 100 % fullständig genomsökning)? Se till att du uppdaterar statistik på båda sidor med samma exempelfrekvens.
Skillnader på databaskompatibilitetsnivå
Kontrollera om databasernas kompatibilitetsnivåer skiljer sig mellan de två servrarna. Kör följande fråga för att hämta databasens kompatibilitetsnivå:
SELECT name, compatibility_level FROM sys.databases WHERE name = '<YourDatabase>'
Skillnader mellan serverversioner och versioner
Skiljer sig versionerna eller versionerna av SQL Server mellan de två servrarna? Är till exempel en server SQL Server version 2014 och den andra SQL Server-versionen 2016? Det kan finnas produktändringar som kan leda till ändringar i hur en frågeplan väljs. Se till att du jämför samma version och version av SQL Server.
SELECT ServerProperty('ProductVersion')
Skillnader i kardinalitetsuppskattning (CE)
Kontrollera om den äldre kardinalitetsberäknaren är aktiverad på databasnivå. Mer information om CE finns i Kardinalitetsuppskattning (SQL Server).
SELECT name, value, is_value_default FROM sys.database_scoped_configurations WHERE name = 'LEGACY_CARDINALITY_ESTIMATION'
Snabbkorrigeringar för optimerare aktiverade/inaktiverade
Om snabbkorrigeringarna för frågeoptimeraren är aktiverade på en server men inaktiverade på den andra, kan olika frågeplaner genereras. Mer information finns i SQL Server query optimizer hotfix trace flag 4199 servicing model (Sql Server query optimizer hotfix trace flag 4199 servicing model).
Kör följande fråga för att hämta tillståndet för snabbkorrigeringar för frågeoptimerare:
-- 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'
Skillnader i spårningsflaggor
Vissa spårningsflaggor påverkar val av frågeplan. Kontrollera om det finns spårningsflaggor aktiverade på en server som inte är aktiverade på den andra. Kör följande fråga på båda servrarna och jämför resultatet:
-- Check at server level for trace flags DBCC TRACESTATUS (-1)
Maskinvaruskillnader (CPU-antal, minnesstorlek)
Kör följande fråga för att hämta maskinvaruinformationen:
SELECT cpu_count, physical_memory_kb/1024/1024 PhysicalMemory_GB FROM sys.dm_os_sys_info
Maskinvaruskillnader enligt frågeoptimeraren
Kontrollera i
OptimizerHardwareDependentProperties
en frågeplan och se om maskinvaruskillnader anses vara betydande för olika planer.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>%'
Timeout för optimizer
Finns det ett timeout-problem för optimeraren? Frågeoptimeraren kan sluta utvärdera planalternativ om frågan som körs är för komplex. När den stoppas väljer den planen med den lägsta tillgängliga kostnaden vid den tidpunkten. Detta kan leda till vad som verkar vara ett godtyckligt planval på en server jämfört med en annan.
SET-alternativ
Vissa SET-alternativ påverkar planen, till exempel SET ARITHABORT. Mer information finns i SET-alternativ.
Skillnader i frågetips
Använder den ena frågan frågetips och den andra inte? Kontrollera frågetexten manuellt för att fastställa förekomsten av frågetips.
Parameterkänsliga planer (problem med parametersniffning)
Testar du frågan med exakt samma parametervärden? Annars kan du börja där. Kompilerades planen tidigare på en server baserat på ett annat parametervärde? Testa de två frågorna med hjälp av RECOMPILE-frågetipset för att säkerställa att ingen plan återanvänds. Mer information finns i Undersöka och lösa parameterkänsliga problem.
Olika databasalternativ/begränsade konfigurationsinställningar
Används samma databasalternativ eller begränsade konfigurationsinställningar på båda servrarna? Vissa databasalternativ kan påverka planval. Till exempel databaskompatibilitet, äldre CE jämfört med standard-CE och parametersniffning. Kör följande fråga från en server för att jämföra databasalternativen som används på de två servrarna:
-- 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
Planguider
Används några planguider för dina frågor på en server, men inte på den andra? Kör följande fråga för att fastställa skillnader:
SELECT * FROM sys.plan_guides