1. Um die Abfrage zu optimieren, sollten Sie versuchen, ein vollständiges Tabellen-Scannen zu vermeiden und zunächst einen Index für die beteiligten Spalten in Wo und nach Sortierung erstellen.
2. Versuchen Sie, Nullwerturteile bei Feldern in der Where-Klausel zu vermeiden, andernfalls wird die Engine die Verwendung von Indizes aufgeben und stattdessen vollständige Tabellenscans durchführen, wie zum Beispiel:
Wähle ID aus T aus, wobei Num null ist
Du kannst den Standardwert auf 0 auf der Zahl setzen, sicherstellen, dass kein Nullwert in der Num-Spalte in der Tabelle steht, und dann so abfragen:
Wähle ID aus T aus, wobei Num=0
3. Versuchen Sie, die Verwendung von != oder <> Operatoren in der where-Klausel zu vermeiden, sonst verzichtet die Engine auf die Verwendung von Indizes und führt ein vollständiges Tabellen-Scannen durch.
4. Du solltest versuchen, OR in der where-Klausel nicht zu verwenden, um der Bedingung beizutreten, da die Engine dadurch die Verwendung von Indizes aufgibt und stattdessen einen vollständigen Tabellen-Scan durchführt, wie zum Beispiel:
Wähle id aus T aus, wobei num=10 oder num=20 sind
Du kannst so eine Anfrage machen:
Wähle ID aus T aus, wobei Num=10
Vereinigung ALLE
Wähle id aus T aus, wobei num=20
5.in und nicht in sollte ebenfalls mit Vorsicht verwendet werden, andernfalls führt es zu vollständigen Tischscans, wie zum Beispiel:
Wähle ID aus T aus, wo num in(1,2,3)
Für kontinuierliche Werte verwenden Sie nicht in, wenn Sie zwischen:
Wähle ID aus T aus, wo Num zwischen 1 und 3 liegt
6. Die folgende Abfrage führt ebenfalls zu einem vollständigen Tabellenscan:
Wähle ID aus T aus, wo Name wie '%abc%'
Um die Effizienz zu steigern, sollten Sie eine Volltextsuche in Betracht ziehen.
7. Wenn Sie einen Parameter in einer where-Klausel verwenden, führt das ebenfalls zu einem vollständigen Tabellenscan. Da SQL nur lokale Variablen zur Laufzeit auflöst, aber der Optimierer die Auswahl der Zugriffspläne nicht auf die Laufzeit verschieben kann; Sie muss zur Kompilierungszeit ausgewählt werden. Wenn jedoch ein Zugriffsplan zur Kompilierungszeit erstellt wird, ist der Wert der Variable weiterhin unbekannt und kann daher nicht als Eingabeelement für die Indexauswahl verwendet werden. Die folgenden Aussagen werden vollständig eingescannt:
Wähle ID aus T aus, wobei num=@num
Sie können die Abfrage dazu zwingen, stattdessen einen Index zu verwenden:
Wählen Sie die ID aus T mit(Index(Index(Indexname)), wobei num=@num
8. Versuchen Sie, Felder in der where-Klausel nicht auszudrücken, da dies dazu führen würde, dass die Engine die Verwendung von Indizes zugunsten eines vollständigen Tabellenscans aufgibt. Zum Beispiel:
Wähle ID aus T aus, wobei num/2=100
sollte geändert werden zu:
Wähle ID aus T aus, wobei num=100*2
9. Versuchen Sie, Funktionsoperationen auf Feldern in der where-Klausel zu vermeiden, da die Engine die Verwendung von Indizes zugunsten eines vollständigen Tabellenscans aufgibt. Zum Beispiel:
Wähle ID aus T aus, wobei Substring(name,1,3)='abc' – Name ID, das mit abc beginnt,
Wählen Sie die ID aus T aus, wo datediff(day, createdate,'2005-11-30')=0--'2005-11-30' generierte ID erstellt wurde
sollte geändert werden zu:
Wähle die ID aus T aus, wo Name wie 'abc%' zum Beispiel 'abc%'
Wählen Sie die ID aus T aus, wo CreateDate>='2005-11-30' und CreateDate<'2005-12-1'
10. Führen Sie keine Funktionen, arithmetischen Operationen oder andere Ausdrucksoperationen links vom "=" in der where-Klausel aus, da das System den Index möglicherweise nicht korrekt verwenden kann.
11. Wenn ein Indexfeld als Bedingung verwendet wird, muss bei Index ein zusammengesetzter Index das erste Feld im Index als Bedingung verwendet werden, um sicherzustellen, dass das System den Index verwendet, andernfalls wird der Index nicht verwendet, und die Reihenfolge der Felder sollte so weit wie möglich mit der Indexreihenfolge übereinstimmen.
12. Schreibe keine bedeutungslosen Abfragen, wie zum Beispiel das Erstellen einer leeren Tabellenstruktur:
Kol1,kol2 in #t aus T wählen, wobei 1=0
Dieser Codetyp liefert keine Ergebnismenge zurück, verbraucht aber Systemressourcen, daher sollte er in so etwas geändert werden:
Tabelle erstellen #t(...)
13. Oft ist es eine gute Wahl, sie mit existierenden zu ersetzen:
Wähle Num aus A, wo Num in (Um aus B auswählen)
Ersetzen Sie durch folgende Aussage:
Wählen Sie Num aus A aus, wo existiert (1 aus B wählen, wo Num=A.Num)
14. Nicht alle Indizes sind für Abfragen gültig, SQL basiert auf den Daten in der Tabelle, um die Abfrage zu optimieren; wenn die Indexspalte eine große Menge an Datenduplikationen enthält, verwenden SQL-Abfragen möglicherweise keinen Index, zum Beispiel eine Tabelle mit einem Feld, das Geschlecht, männlich, weiblich ist fast die Hälfte, und selbst wenn der Index auf Geschlecht basiert, spielt er keine Rolle für die Effizienz der Abfrage.
15. Je mehr Indizes nicht sind, desto besser – der Index kann die Effizienz des entsprechenden Selects sicherlich verbessern, aber er verringert auch die Effizienz von Insert und Update, da der Index beim Einfügen oder Aktualisieren neu aufgebaut werden kann, sodass die Erstellung eines Index je nach Situation sorgfältig überlegt werden muss. Es ist am besten, nicht mehr als 6 Indizes in einer Tabelle zu haben, und wenn es zu viele sind, überlegen Sie, ob es notwendig ist, auf selten verwendeten Spalten Indizes zu erstellen.
16. Vermeiden Sie es, die Spalten der clusterierten Indexdaten so weit wie möglich zu aktualisieren, da die Reihenfolge der Spalten der Indexdatensätze die physische Speicherreihenfolge der Tabellendatensätze entspricht, und sobald sich der Spaltenwert ändert, führt dies zur Anpassung der Reihenfolge aller Tabellendatensätze, was erhebliche Ressourcen beansprucht. Wenn Ihre Anwendung häufig die Spalten des Cluster-Index aktualisieren muss, sollten Sie überlegen, ob Sie den Index als Cluster-Index erstellen sollten.
17. Versuchen Sie, numerische Felder zu verwenden und vermeiden Sie, Felder zu entwerfen, die nur numerische Informationen als Zeichen enthalten, da dies die Leistung von Abfragen und Verbindungen verringert und den Speicheraufwand erhöht. Das liegt daran, dass die Engine jedes Zeichen der Zeichenkette einzeln vergleicht, wenn Abfragen und Joins verarbeitet werden, während sie bei numerischen Typen nur einmal verglichen werden muss.
18. Verwenden Sie so oft wie möglich varchar/nvarchar statt char/nchar, denn erstens kann der längere Feldspeicherplatz Speicherplatz sparen, und zweitens ist bei Abfragen die Sucheffizienz in einem relativ kleinen Feld offensichtlich höher.
19. Verwenden Sie nirgendwo "select * from t", ersetzen Sie "*" durch eine bestimmte Liste von Feldern und geben Sie keine Felder zurück, die nicht verwendet wurden.
20. Versuche, Tabellenvariablen statt temporärer Tabellen zu verwenden. Wenn die Tabellenvariable eine große Datenmenge enthält, beachten Sie, dass der Index sehr begrenzt ist (nur der Primärschlüsselindex).
21. Vermeiden Sie häufiges Erstellen und Löschen temporärer Tabellen, um den Verbrauch von Systemtabellenressourcen zu verringern.
22. Temporäre Tabellen sind nicht unbrauchbar, und deren angemessene Nutzung kann einige Routinen effektiver machen, zum Beispiel wenn man einen Datensatz in einer großen oder häufig verwendeten Tabelle wiederholt referenzieren muss. Für einmalige Ereignisse ist es jedoch am besten, eine Exporttabelle zu verwenden.
23. Beim Erstellen einer temporären Tabelle, wenn die gleichzeitig eingefügten Datenmenge groß ist, kann man auswählen in statt 'Tabelle erstellen' verwenden, um zu vermeiden, dass eine große Anzahl von Logs verursacht wird, was die Geschwindigkeit verbessert; Wenn die Datenmenge nicht groß ist, solltest du, um die Ressourcen der Systemtabelle zu erleichtern, zuerst eine Tabelle erstellen und dann einfügen.
24. Wenn eine temporäre Tabelle verwendet wird, sollten alle temporären Tabellen am Ende der gespeicherten Prozedur explizit gelöscht, zuerst die Tabelle abgeschnitten und dann die Tabelle entfernt werden, um zu vermeiden, dass die Systemtabelle für längere Zeit gesperrt wird.
25. Versuche, den Cursor nicht zu verwenden, da die Effizienz des Cursors schlecht ist; wenn die vom Cursor gesteuerten Daten mehr als 10.000 Zeilen überschreiten, solltest du eine Umschreibung in Betracht ziehen.
26. Set-basierte Lösungen sollten vor Verwendung von cursorbasierten oder temporären Tabellenmethoden, die oft effektiver sind, nach Lösungen gesucht, um Probleme zu lösen.
27. Wie temporäre Tabellen sind Cursor nicht unbrauchbar. Die Verwendung FAST_FORWARD Cursors für kleine Datensätze ist oft besser als andere Reihen-für-Zeilen-Verarbeitungsmethoden, besonders wenn man mehrere Tabellen referenzieren muss, um die benötigten Daten zu erhalten. Routinen, die "total" im Ergebnisset enthalten, sind in der Regel schneller als solche, die mit dem Cursor ausgeführt werden. Wenn die Entwicklungszeit es erlaubt, können sowohl cursorbasierte als auch mengenbasierte Methoden ausprobiert werden, um herauszufinden, welche besser funktioniert.
28. Setze SET NOCOUNT ON zu Beginn aller gespeicherten Prozeduren und Trigger und SET NOCOUNT OFF am Ende. Es ist nicht notwendig, DONE_IN_PROC Nachrichten nach Ausführung jeder Anweisung der gespeicherten Prozedur und des Triggers an den Client zu senden.
29. Versuche, große Transaktionsoperationen zu vermeiden und die Konkurrenzkapazität des Systems zu verbessern.
30. Versuchen Sie, große Daten nicht an den Kunden zurückzugeben; wenn das Datenvolumen zu groß ist, sollten Sie prüfen, ob die entsprechende Nachfrage angemessen ist. |