Heim  >  Artikel  >  Betrieb und Instandhaltung  >  So schreiben Sie hochwertige und leistungsstarke SQL-Abfrageanweisungen

So schreiben Sie hochwertige und leistungsstarke SQL-Abfrageanweisungen

WBOY
WBOYnach vorne
2023-05-12 21:04:121351Durchsuche

1. Zunächst müssen wir verstehen, was ein Ausführungsplan ist.

Der Ausführungsplan ist ein von der Datenbank erstellter Abfrageplan, der auf den statistischen Informationen der SQL-Anweisung und zugehörigen Tabellen basiert. Dieser Plan wird automatisch vom Abfrageoptimierer analysiert, wenn beispielsweise eine SQL-Anweisung zum Abfragen einer Tabelle verwendet wird 100.000 Datensätze, 1 Datensatz, der Abfrageoptimierer wählt die Methode „Indexsuche“. Wenn die Tabelle archiviert ist und nur noch 5.000 Datensätze vorhanden sind, ändert der Abfrageoptimierer den Plan und verwendet die Methode „Vollständiger Tabellenscan“.

Man erkennt, dass der Ausführungsplan nicht festgelegt, sondern „personalisiert“ ist. Bei der Erstellung eines korrekten „Ausführungsplans“ gibt es zwei wichtige Punkte:

(1) Sagt die SQL-Anweisung dem Abfrageoptimierer klar, was er tun möchte?

(2) Sind die vom Abfrageoptimierer ermittelten Datenbankstatistiken aktuell und korrekt?

2. Vereinheitlichen Sie die Art und Weise, SQL-Anweisungen zu schreiben.

Bei den folgenden beiden SQL-Anweisungen denken Programmierer, dass sie gleich sind, der Datenbankabfrageoptimierer geht jedoch davon aus, dass sie unterschiedlich sind.

select*from dual

select*From dual

Tatsächlich ist der Fall anders. Der Abfrageanalysator betrachtet es als zwei verschiedene SQL-Anweisungen und muss zweimal analysiert werden. Generieren Sie 2 Ausführungspläne. Daher sollten Sie als Programmierer sicherstellen, dass überall dieselbe Abfrageanweisung konsistent ist. Selbst ein Leerzeichen mehr funktioniert nicht!

3. Beim Schreiben von SQL-Anweisungen zu beachtende Punkte

Im Folgenden finden Sie eine detaillierte Einführung in einige beim Schreiben von SQL-Anweisungen zu beachtende Punkte. In diesen where-Klauseln kann das System den Index beim Ausführen der SQL-Anweisung nicht verwenden, selbst wenn für einige Spalten Indizes vorhanden sind, da SQL von schlechter Qualität ist, und verwendet außerdem einen vollständigen Tabellenscan, was zu einer extrem langsamen Antwortgeschwindigkeit führt Reduktion.

1.IST NULL und IST NICHT NULL

Sie können Null nicht als Index verwenden und jede Spalte, die einen Nullwert enthält, wird nicht in den Index aufgenommen. Selbst wenn der Index mehrere Spalten enthält, wird die Spalte aus dem Index ausgeschlossen, solange eine dieser Spalten Null enthält. Das heißt, wenn eine Spalte einen Nullwert enthält, verbessert selbst die Erstellung eines Indexes für die Spalte die Leistung nicht.

Jeder Anweisungsoptimierer, der in einer where-Klausel null oder nicht null verwendet, darf keine Indizes verwenden.

2. Vermeiden Sie die Verwendung inkompatibler Datentypen.

Der inkompatible Datentyp stellt die Typkonvertierung der vollständigen Tabellenabrufdaten dar, und der Zugriff wird zu einem vollständigen Tabellenscan

Bei denjenigen mit Join-Spalten gilt: Selbst wenn der endgültige Join-Wert ein statischer Wert ist, verwendet der Optimierer den Index nicht. Schauen wir uns ein Beispiel an. Angenommen, es gibt eine Mitarbeitertabelle (Mitarbeiter). Der Vor- und Nachname eines Mitarbeiters wird in zwei Spalten gespeichert (FIRST_NAME und NACHNAME).

Das Folgende ist eine SQL-Anweisung, die eine Join-Abfrage verwendet:

select * from equipess where first_name||''||last_name ='Beill Cliton';

Die obige Anweisung kann vollständig abfragen, ob es einen Mitarbeiter Bill Cliton gibt. Hierbei ist jedoch zu beachten, dass der Systemoptimierer nicht den auf Basis des Nachnamens erstellten Index verwendet.

Wenn die folgende SQL-Anweisung geschrieben wird, kann das Oracle-System den basierend auf Nachname erstellten Index verwenden.

*** wobei Vorname ='Beill' und Nachname ='Cliton';

4. Wie eine Anweisung, die mit einem Platzhalterzeichen beginnt (%)

Die aktuelle Anforderung lautet: Es ist erforderlich, die Mitarbeitertabelle nach Namen abzufragen, die enthalten Kliton-Leute. Sie können die folgende Abfrage-SQL-Anweisung verwenden:

Wählen Sie * von Mitarbeiter aus, wobei Nachname wie „%cliton%“ lautet. Da das Platzhalterzeichen (%) am Anfang des Suchworts erscheint, verwendet das Oracle-System hier nicht den Index von Nachname. Wenn jedoch Platzhalter an anderer Stelle in der Zeichenfolge erscheinen, kann der Optimierer den Index nutzen. Der Index wird in der folgenden Abfrage verwendet:

Wählen Sie * vom Mitarbeiter aus, wobei Nachname wie „c%“ lautet.

5 Durch das Ausführen von Vorgängen am Indexfeld wird der Index ungültig.

Vermeiden Sie die Ausführung von Funktions- oder Ausdrucksoperationen für Felder in der WHERE-Klausel, da dies dazu führen würde, dass die Engine die Verwendung des Index aufgibt und einen vollständigen Tabellenscan durchführt.

Beispiel: SELECT * FROM T1 WHERE F1/2=100 sollte geändert werden in: SELECT * FROM T1 WHERE F1=100*2

6. Die Anweisung „Order by“ bestimmt, wie Oracle die zurückgegebenen Abfrageergebnisse sortiert. Die Order by-Anweisung unterliegt keinen besonderen Einschränkungen hinsichtlich der zu sortierenden Spalten, und den Spalten können auch Funktionen hinzugefügt werden (z. B. Verknüpfungen oder Anhänge usw.). Alle Nicht-Indexelemente oder berechneten Ausdrücke in der Order by-Anweisung verlangsamen die Abfrage.

Überprüfen Sie die Order by-Anweisungen sorgfältig auf nicht indizierte Elemente oder Ausdrücke, die die Leistung beeinträchtigen können. Die Lösung für dieses Problem besteht darin, die order by-Anweisung so umzuschreiben, dass ein Index verwendet wird. Sie können auch einen anderen Index für die verwendete Spalte erstellen. Gleichzeitig sollten Sie die Verwendung von Ausdrücken in der order by-Klausel unbedingt vermeiden.

7. NICHT

Bei Abfragen verwenden wir häufig einige logische Ausdrücke in der Where-Klausel, z. B. größer als, kleiner als, gleich, ungleich usw. Wir können auch und (und) oder (oder) verwenden und nicht (nicht ). NOT kann verwendet werden, um jedes Vorzeichen einer logischen Operation zu negieren. Hier ist ein Beispiel für eine NOT-Klausel:

... where not (status ='VALID')

Wenn Sie NOT verwenden möchten, sollten Sie vor der negierten Phrase Klammern und vor der Phrase den NOT-Operator setzen. Der NOT-Operator ist in einem anderen logischen Operator enthalten, dem Ungleich-Operator (<>). Mit anderen Worten: Auch wenn das NOT-Wort nicht explizit zur where-Klausel der Abfrage hinzugefügt wird, befindet sich NOT immer noch im Operator, siehe folgendes Beispiel:

... where status <>'INVALID'

Für diese Abfrage kann sie so umgeschrieben werden, dass NOT nicht verwendet wird:

Wählen Sie * vom Mitarbeiter mit Gehalt<3000 oder Gehalt>3000; aus.

Obwohl die Ergebnisse dieser beiden Abfragen gleich sind, ist der zweite Abfrageplan schneller als der erster Abfrageplan. Die zweite Abfrage ermöglicht Oracle die Verwendung von Indizes für die Gehaltsspalte, während die erste Abfrage keine Indizes verwenden kann.

8. IN und EXISTS

Manchmal wird eine Spalte mit einer Reihe von Werten verglichen. Der einfachste Weg besteht darin, eine Unterabfrage in der where-Klausel zu verwenden. In der where-Klausel können zwei Formate von Unterabfragen verwendet werden.

Das erste Format ist die Verwendung des IN-Operators:

... where Column in (select * from ... where ...);

Das zweite Format ist die Verwendung des EXIST-Operators:

... where is (select 'X' from ...where ...);

Ich glaube, die meisten Leute werden das erste Format verwenden, weil es einfacher zu schreiben ist, aber tatsächlich ist das zweite Format weitaus besser als das erste. Dieses Format ist hocheffizient. In Oracle können fast alle IN-Operator-Unterabfragen mithilfe von EXISTS in Unterabfragen umgeschrieben werden.

Im zweiten Format beginnt die Unterabfrage mit „select ‚X‘“. Bei Verwendung der EXISTS-Klausel wird unabhängig davon, welche Daten die Unterabfrage aus der Tabelle extrahiert, nur die Where-Klausel berücksichtigt. Auf diese Weise muss der Optimierer nicht die gesamte Tabelle durchlaufen und kann die Arbeit nur auf der Grundlage des Index abschließen (dies setzt voraus, dass die in der where-Anweisung verwendete Spalte über einen Index verfügt). Im Vergleich zur IN-Klausel verwendet EXISTS verbundene Unterabfragen, die schwieriger zu erstellen sind als IN-Unterabfragen.

Durch die Verwendung von EXIST prüft das Oracle-System zuerst die Hauptabfrage und führt dann die Unterabfrage aus, bis es die erste Übereinstimmung findet, was Zeit spart. Wenn das Oracle-System die IN-Unterabfrage ausführt, führt es zunächst die Unterabfrage aus und speichert die erhaltene Ergebnisliste in einer indizierten temporären Tabelle. Bevor die Unterabfrage ausgeführt wird, unterbricht das System zunächst die Hauptabfrage. Nachdem die Unterabfrage abgeschlossen ist, wird sie in der temporären Tabelle gespeichert und dann wird die Hauptabfrage ausgeführt. Aus diesem Grund ist die Verwendung von EXISTS für allgemeine Abfragen schneller als die Verwendung von IN.

Gleichzeitig sollte so oft wie möglich NOT EXISTS anstelle von NOT IN verwendet werden. Obwohl beide NOT verwenden (der Index kann nicht zur Geschwindigkeitsreduzierung verwendet werden), ist NOT EXISTS effizienter als NOT IN-Abfragen.

9. Vermeiden Sie die Verwendung von oder in der where-Klausel, um Bedingungen zu verbinden, da die Engine sonst die Verwendung des Index aufgibt und einen vollständigen Tabellenscan durchführt.

Zum Beispiel: Wählen Sie die ID des Mitarbeiters aus, wobei Nummer = 10 oder Nummer = 20 ist

Okay. Abfrage wie folgt: Wählen Sie die ID des Mitarbeiters aus, wobei Anzahl = 10. Alle IDs des Mitarbeiters auswählen, wobei Anzahl = 20. Sie sollten versuchen, Ausdrucksoperationen für Felder in der Where-Klausel zu vermeiden. Dies führt dazu, dass die Engine nicht funktioniert Geben Sie die Verwendung des Index auf und führen Sie den vollständigen Tabellenscan durch. Beispiel: select id from t where num/2=100 sollte geändert werden in: select id from t where num=100*2

11 Versuchen Sie, funktionale Operationen an Feldern in der where-Klausel zu vermeiden

Dies wird dazu führen Engine gibt auf. Führen Sie einen vollständigen Tabellenscan mit einem Index durch. Beispiel: Wählen Sie eine ID aus t aus, wobei Teilzeichenfolge (Name, 1,3) = „abc“ ist. Die ID, deren Name mit abc beginnt, sollte geändert werden in:

Wählen Sie eine ID aus t aus, wobei der Name „abc%“ lautet

12. Nicht verwenden where Die linke Seite von „=“ in der Klausel muss Funktionen, arithmetische Operationen oder andere Ausdrucksoperationen ausführen, da das System sonst den Index möglicherweise nicht korrekt verwenden kann.

13. Wenn Sie ein Indexfeld als Bedingung verwenden und der Index ein zusammengesetzter Index ist, muss 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 Feldreihenfolge sollte so weit wie möglich mit der Indexreihenfolge übereinstimmen.

14. Je mehr Indizes, desto besser

Obwohl Indizes die Effizienz der entsprechenden Auswahl verbessern können, verringern sie auch die Effizienz des Einfügens und Aktualisierens, da der Index möglicherweise während des Einfügens oder Aktualisierens neu erstellt wird Index ist erforderlich. Sorgfältig und von Fall zu Fall prüfen. Es ist am besten, nicht mehr als 6 Indizes für eine Tabelle zu haben. Wenn es zu viele sind, sollten Sie überlegen, ob es notwendig ist, Indizes für einige Spalten zu erstellen, die nicht häufig verwendet werden.

15. Versuchen Sie, numerische Felder zu verwenden, versuchen Sie, sie nicht als Zeichenfelder zu gestalten. Dies verringert die Leistung von Abfragen und Verbindungen und erhöht den Speicheraufwand. Dies liegt daran, dass die Engine bei der Verarbeitung von Abfragen und Verbindungen jedes Zeichen in der Zeichenfolge einzeln vergleicht und für numerische Typen nur ein Vergleich ausreicht.

16. Verwenden Sie so oft wie möglich varchar/nvarchar anstelle von char/nchar, da erstens der Speicherplatz von Feldern variabler Länge klein ist, was zweitens die Sucheffizienz in einem relativ kleinen Feld sparen kann ist offensichtlich höher.

17. Verwenden Sie „select * fromt“ nirgendwo, ersetzen Sie „*“ durch eine bestimmte Feldliste und geben Sie keine nicht verwendeten Felder zurück.

Das obige ist der detaillierte Inhalt vonSo schreiben Sie hochwertige und leistungsstarke SQL-Abfrageanweisungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen