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:

    1. 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).
    2. Kör frågorna på de två servrarna.
    3. Jämför den förflutna tiden (varaktigheten) på två servrar för varje fråga.
  • Analysera prestandadata med SQL Nexus.

    1. Samla in PSSDiag/SQLdiag - eller SQL LogScout-data för frågorna på de två servrarna.
    2. 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 IO ON.

    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.

    1. Kör frågan med Inkludera faktisk körningsplan på.

    2. Välj operatorn längst till vänster från Körningsplan.

    3. Från Egenskaper expanderar du egenskapen QueryTimeStats .

    4. Kontrollera ElapsedTime och CpuTime.

      Skärmbild av fönstret för SQL Server-körningsplanegenskaper med egenskapen QueryTimeStats expanderad.

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

  1. 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:
  2. 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

  1. Kontrollera spårningar på båda servrarna för följande:

    1. Om det finns någon spårning aktiverad på Server1 men inte på Server2.
    2. Om någon spårning är aktiverad inaktiverar du spårningen och kör frågan igen på Server1.
    3. 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.
  2. Kontrollera om frågan använder UDF:er som utför strängmanipuleringar eller utför omfattande bearbetning av datakolumner i SELECT listan.

  3. 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:

    1. Kör frågan med Inkludera faktisk körningsplan på.
    2. Högerklicka på operatorn längst till vänster på fliken Körningsplan
    3. Välj Egenskaper och sedan egenskapen WaitStats .
    4. 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:

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