Mssql Ausführungsplan

  • SQL

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ISliceUrPanties.

    Hallo,
    so ganz klar ist deine Frage nicht. Worum geht's dir dabei? Um die Performance oder einfach, was die Schritte in dem Ausführungsplan bedeuten?

    Grundlegend kann man sagen, wenn man sich so einen Ausführungsplan anschaut und es die um Performance geht, sollte man sich immer zuerst die Table Scans anschauen. Das ist zwar die grundlegendste Funktion, aber meist auch die teuerste. Einen Table Scan möchte man im Allgemeinen immer vermeiden, da dadurch eine Tabelle von der ersten bis zur Letzten Zeile durchsucht wird. Sollte deine Tabelle relativ breit und sehr viele Daten enthalten, ist ein Table Scan die langsamste Operation. Man kann über die Items in dem Ausführungsplan hovern, um mehr Informationen über die Aktion zu erfahren, z.B. wie hoch die Kosten auf dem Datenträger oder der CPU waren und welcher Schlüssel/Index verwendet wurde.
    Ein Table Scan verwendet offensichtlich keinen Index. Das kann bei dir verschiedene Ursachen haben. Du hast z.B. keine Indizes auf deinen Tabellen, oder die Query Engine hat entschieden, dass bei deiner kleinen Tabelle der Table Scan schneller ist, als einen Index abzufragen.
    Wie gesagt, bei größeren Tabellen sollte im Ausführungsplan niemals ein Table Scan auftauchen, sondern besser, ein (Clustured) Index Scan oder im Idealfall ein (Clustured) Index Seek. Die Query Engine des SQL-Servers sucht sich den für dein SQL-Statement besten Index und durchsucht diesen nach den Werten. Da ein Index nicht alle Daten der Tabelle enthält, kann hier viel schneller gesucht und gefunden werden.
    Hier mal ein paar Beispiele, wie das ganze mit größeren Tabellen aussehen kann. Mein Statement ist ein einfaches Select, Primärschlüssel meiner gewählten Tablle ist das Feld No_.
    Spoiler anzeigen

    SQL-Abfrage

    1. SELECT TOP (100) [timestamp]
    2. ,[No_]
    3. ,[Name]
    4. ,[Search Name]
    5. ,[Name 2]
    6. ,[Address]
    7. ,[Address 2]
    8. ,[City]
    9. ,[Contact]
    10. ,[Phone No_]
    11. ,[Telex No_]
    12. ,[Document Sending Profile]
    13. ,[Ship-to Code]
    14. ,[Our Account No_]
    15. ,[Territory Code]
    16. ,[Global Dimension 1 Code]
    17. ,[Global Dimension 2 Code]
    18. ,[Chain Name]
    19. ,[Budgeted Amount]
    20. ,[Credit Limit (LCY)]
    21. ,[Customer Posting Group]
    22. ,[Currency Code]
    23. ,[Customer Price Group]
    24. ,[Language Code]
    25. ,[Statistics Group]
    26. ,[Payment Terms Code]
    27. ,[Fin_ Charge Terms Code]
    28. ,[Salesperson Code]
    29. ,[Shipment Method Code]
    30. ,[Shipping Agent Code]
    31. ,[Place of Export]
    32. ,[Invoice Disc_ Code]
    33. ,[Customer Disc_ Group]
    34. ,[Country_Region Code]
    35. ,[Collection Method]
    36. ,[Amount]
    37. ,[Blocked]
    38. ,[Invoice Copies]
    39. ,[Last Statement No_]
    40. ,[Print Statements]
    41. ,[Bill-to Customer No_]
    42. ,[Priority]
    43. ,[Payment Method Code]
    44. ,[Last Modified Date Time]
    45. ,[Last Date Modified]
    46. ,[Application Method]
    47. ,[Prices Including VAT]
    48. ,[Location Code]
    49. ,[Fax No_]
    50. ,[Telex Answer Back]
    51. ,[VAT Registration No_]
    52. ,[Combine Shipments]
    53. ,[Gen_ Bus_ Posting Group]
    54. ,[Picture]
    55. ,[GLN]
    56. ,[Post Code]
    57. ,[County]
    58. ,[EORI Number]
    59. ,[Use GLN in Electronic Document]
    60. ,[E-Mail]
    61. ,[Home Page]
    62. ,[Reminder Terms Code]
    63. ,[No_ Series]
    64. ,[Tax Area Code]
    65. ,[Tax Liable]
    66. ,[VAT Bus_ Posting Group]
    67. ,[Reserve]
    68. ,[Block Payment Tolerance]
    69. ,[IC Partner Code]
    70. ,[Prepayment _]
    71. ,[Partner Type]
    72. ,[Image]
    73. ,[Privacy Blocked]
    74. ,[Disable Search by Name]
    75. ,[Preferred Bank Account Code]
    76. ,[Cash Flow Payment Terms Code]
    77. ,[Primary Contact No_]
    78. ,[Contact Type]
    79. ,[Responsibility Center]
    80. ,[Shipping Advice]
    81. ,[Shipping Time]
    82. ,[Shipping Agent Service Code]
    83. ,[Service Zone Code]
    84. ,[Allow Line Disc_]
    85. ,[Base Calendar Code]
    86. ,[Copy Sell-to Addr_ to Qte From]
    87. ,[Validate EU Vat Reg_ No_]
    88. ,[Id]
    89. ,[Currency Id]
    90. ,[Payment Terms Id]
    91. ,[Shipment Method Id]
    92. ,[Payment Method Id]
    93. ,[Tax Area ID]
    94. ,[Contact ID]
    95. ,[Contact Graph Id]
    96. FROM [Demo Database NAV (14-0) CU31].[dbo].[CRONUS AG$Customer]

    Wenn ich das Statement so ausführe, entscheidet die Query Engine, dass die Datensätze über den Primärschlüssel zusammengesucht werden. Da alle Daten zurückgegeben werden müssen, wird ein Index Scan durchgeführt. In dem Bild erkennt man an der rot markierten Stelle im Tooltip des Index Scans bei Object, welcher Schlüssel verwendet wird.


    Wenn ich mein Statement um eine WHERE-Klausel erweitere, ändert sich auch der Ausführungsplan.

    SQL-Abfrage

    1. ​WHERE [Search Name] = 'MÖBEL-MELLER KG'


    Neben einem Index Seek, habe ich hier in meinem Beispiel jetzt auch ein Key Lookup.

    Man sieht im Tooltip für den Index Seek, dass die Query Engine sich nicht mehr für den Primärschlüssel, sondern einen anderen Index entschieden hat. Der Key Lookup wird jetzt zus. ausgeführt, weil in dem Index nicht alle Felder enthalten sind, die zurück gegeben werden sollen.

    Solltest du mehr darüber wissen wollen, kann ich dir auf Grund der Komplexität dieses Themas eine Schulung über den SQL-Server ans Herz legen.
    Danke dir, hast du vielleicht noch ein paar Erfahrungswerte was die Werte angeht die gut wären?
    Also wenn ich z.B. ein Query habe die wenige Millisekunden benötigt, brauche ich mir wahrscheinlich nicht viel Gedanken zu dem Ausführungsplan zu machen.

    Achja und was ich noch fragen wollte: Kann man einer Query auch direkt sagen welche Zeile zurückgegeben werden soll
    (Also ich weiß das macht keinen Sinn, aber sagen wir ich schaue mit menschlichem Auge über die Tabelle und sage Zeile 4 passt, kann ich dann nur die Zeile anfordern ohne das sql selbst suchen muss?)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Danke dir, hast du vielleicht noch ein paar Erfahrungswerte was die Werte angeht die gut wären?

    Kommt immer drauf an, wie viele Benutzer die Datenbank verwenden und wie Geduldig diese sind ;). Ich schaue mir immer Querys genauer an, die in einer Produktivumgebung mehr als 1000ms benötigen. Das kann man z.B. mit dem SQL Server Profiler ermitteln. Diese Querys führe ich dann manuell mit dem Management-Studio aus, um den Ausführungsplan anzusehen. Number of Rows Read und Number of Executions aus den Tooltips oben sollten im allgemeinen so niedrig wie möglich sein. Aber das hängt letztendlich vom Query selbst ab.

    Haudruferzappeltnoch schrieb:

    Kann man einer Query auch direkt sagen welche Zeile zurückgegeben werden soll

    Ja, das geht, aber "suchen" bzw. lesen muss die Query Engine/der SQL Server immer. Da gibt es zwei Ansätze:
    Wenn ich mein Beispiel-Query von oben verwende, kann man einfach mit einem ORDER BY und einem OFFSET arbeiten.

    SQL-Abfrage

    1. ​ORDER BY [No_] ASC
    2. OFFSET 4 ROWS
    3. FETCH NEXT 1 ROWS ONLY


    Oder man verwendet die ROW_NUMBER Funktion, um dann eine bestimmte Zeile mit WHERE zu bekommen

    SQL-Abfrage

    1. ​SELECT *
    2. FROM
    3. (
    4. SELECT
    5. ROW_NUMBER() OVER (ORDER BY [No_]) AS RowNum
    6. , *
    7. FROM [Demo Database NAV (14-0) CU31].[dbo].[CRONUS AG$Customer]
    8. ) AS t
    9. WHERE RowNum = 5


    P.S.: Niemals SELECT * ... verwenden, das habe ich jetzt hier nur der Einfachhalt halber genommen.
    Ja macht es. Bei einem SELECT * muss der SQL-Server erst alle Spalten über Systemtabellen ermitteln. Das ist halt zusätzliche Arbeit, die eingespart werden kann. Sollte sich über die Zeit dein Tabellenschema ändern, kann dein Programm u.U. mit neuen oder entfernten Spalten nicht umgehen. Man sollte bewusst immer nur die Spalten selektieren, die man benötigt, auch wenn es alle sind.

    Vielleicht ist auch folgendes für dich Interessant. MS hat eine Lernplatform, in der man Module zu verschiedenen Themen durchgehen kann, u.a. auch docs.microsoft.com/en-us/learn…y-performance-sql-server/