Die Optimierung der SQL-Leistung stellt für Programmierer eine große Herausforderung dar, da wir häufig auf dieses Problem stoßen: Wenn wir ein Projekt entwickeln, haben wir das Gefühl, dass die funktionale Erfahrung, es selbst zu testen, wirklich gut ist, aber nachdem das eigentliche Projekt gestartet wurde, Mit der massiven Steigerung In Bezug auf Daten wird das Kundenerlebnis des Systems immer schlechter. Neben dem Framework und dem unvernünftigen Code liegt der Hauptgrund natürlich darin, dass SQL nicht optimiert wurde, was dazu geführt hat, dass das System immer langsamer wurde.
Da ich in einem kleinen Unternehmen arbeite, denke ich, dass es manchmal besser ist, die Symptome zu behandeln, als die Grundursache zu behandeln! Es gibt mehrere Punkte, auf die Sie achten sollten:
1. Das Design der Datenbanktabelle muss angemessen sein, insbesondere das Design des Primärschlüssels. Wenn die Datenmenge in der Tabelle sehr groß ist, sollte das Design des Primärschlüssels nicht aussagekräftig sein, genau wie ROWID GUID von SQL Server, die UUID von Hibernate usw. Natürlich können einige Datenwörterbuchtabellen flexibel verarbeitet werden, und es muss nicht berücksichtigt werden, dass es sich um physische Primärschlüssel handeln muss. Beim Primärschlüsselentwurf werden im Allgemeinen keine zusammengesetzten Primärschlüssel verwendet.
2. Angemessene Indizierung. Index ist ein leistungsstarkes Tool und ein gutes Mittel, um unsere Datenabfrage zu beschleunigen. Aber fügen Sie nicht jedes Feld hinzu. Das Prinzip der Indexierung ähnelt dem Inhaltsverzeichnis eines Buches. Wenn das Inhaltsverzeichnis Ihres Buches fast alle den gleichen Namen hat, können Sie sich Folgendes vorstellen: Wie schnell können Sie den spezifischen Inhalt anhand des Inhaltsverzeichnisses finden? ? Der Index muss nicht unbedingt eindeutig sein, er sollte jedoch nicht zu viele identische Datensätze enthalten. Wenn weitere Indizes hinzugefügt werden, erhöht sich außerdem der Tabellenbereich TEMP. Wenn Sie die Tabelle exportieren und in eine andere Datenbank importieren, wird auch der Tabellenbereich UNDOTBS01 verringert ist ungewöhnlich groß. Daher ist der Index ein zweischneidiges Schwert und muss vernünftig angewendet werden.
3. Ich habe im Internet einige sehr professionelle Artikel über SQL-Optimierung gesehen, aber ich habe das Gefühl, dass ich diese nicht in meinem Projekt verwenden konnte. Stattdessen experimentierte ich weiter und entdeckte während des Projekts einige Grundprinzipien. Ich persönlich denke, dass es nur ein Prinzip der SQL-Optimierung gibt, nämlich den Abfragebereich so weit wie möglich einzuschränken. Dies wird definitiv die Effizienz verbessern, und Oracle selbst kann das SQL, das wir schreiben, optimieren Wenn wir davon sprechen, denke ich, dass die Indizierung ein wirksames Werkzeug zur Verbesserung der Abfragegeschwindigkeit ist und sich auch aus dem Prinzip der Einengung des Abfrageumfangs ergibt .
Die meisten SQL-Anweisungen, die optimiert werden müssen, sind Multi-Table-Join-Abfragen, und Multi-Table-Joins umfassen auch horizontale Joins und vertikale Joins. Am häufigsten verwenden wir vertikale Joins. Horizontale Verbindung bedeutet im Allgemeinen, dass die Feldstrukturen zweier Tabellen grundsätzlich gleich sind und einige Datensätze einer Tabelle in einige Datensätze einer anderen Tabelle geändert werden sollten, nämlich Zeilen + Zeilen. Vertikale Verbindung bedeutet, dass wir einige abzufragende Felder aus Tabelle A und einige abzufragende Felder aus Tabelle B nehmen und dann die aus den Tabellen A und B entnommenen Tabellen mithilfe des gemeinsamen Teils, d. h. Spalten+Spalten, vertikal verbinden.
Horizontale Join-Anweisung: Wählen Sie a.column1,a.column2 aus TabelleA aus. Eine Vereinigung aller Elemente. Wählen Sie b.column1,b.column2 aus TabelleB.b
Beachten Sie, dass bei horizontaler Verbindung die Anzahl der Spalten und die Datentypen der entsprechenden Feldspalten gleich sein müssen. Tatsächlich können Sie sich die zu vereinigenden Tabellen als eine Kopie der anderen vorstellen, also genau das Gleiche. Jemand fragt sich vielleicht: Wenn die Spalten, die ich zusammenführen möchte, unterschiedliche Spalten haben oder überhaupt keine Spalte vorhanden ist, können Sie die folgende Methode verwenden
select d.dname,d.loc from dept1 d union all select '' dname, e.loc from dept e, schauen Sie sich „'' dname“ an. Wir können leicht feststellen, dass Sie einen Ersatz finden können. Verwenden Sie stattdessen eine leere Zeichenfolge Da es keine Felder gibt, können sie zusammengeführt werden.
Vertikale Join-Anweisung: Wählen Sie a.column1,a.column2 aus TabelleA, einen vollständigen Outer-Join, wählen Sie b.column3,b.column4 aus TabelleB, b auf a.aid=b.bid, wobei ... dies ein vollständiges Outer-Join-Format ist. Diese Geschwindigkeit ist zwar sehr hoch, aber die Abfrage gefällt Ihnen möglicherweise nicht, da es einige Ergebniszeilen gibt, die Sie möglicherweise überhaupt nicht sehen möchten. Unter normalen Umständen verwenden wir eher den linken Außen-Join und den rechten Außen-Join. Der Unterschied zwischen den beiden besteht darin, dass der linke Außen-Join hauptsächlich auf der Tabelle basiert, die dem Verbindungsfeld auf der linken Seite entspricht, und der rechte Außen-Join genau das Gegenteil ist. Natürlich können Sie auch Left-Join und Right-Join verwenden. Während der Nutzung habe ich dennoch festgestellt, dass externe Verbindungen relativ schneller sind.
Um die Effizienz vertikaler Verbindungsabfragen zu beschleunigen, besteht die Möglichkeit darin, Abfragen zu verschachteln. Das Folgende ist ein aktuelles Beispiel aus dem Projekt:
Wählen Sie c.customerid,c.receivedmoney,c.tollcollector,c.receiveddate,c.yearmonth,c.receivedlatefee,
c.receivedfee,c.receivedappend,c.jmman,c.jmmoney,c.name,d.chargeint from
(Wählen Sie eine Kunden-ID, ein erhaltenes Geld, einen Mauteintreiber, ein Erhaltsdatum, einen Jahresmonat, eine erhaltene Verspätungsgebühr,
a.receivedfee,a.receivedappend,a.jmman,a.jmmoney,b.name from
(wählen Sie rf.customerid,rf.receivedmoney,rf.tollcollector,rf.receiveddate,rf.yearmonth,rf.receivedlatefee,
rf.receivedfee,rf.receivedappend,rf.jmman,rf.jmmoney von sf_receivedfee rf wo
rf.electriccompanyid='1000000001' und rf.dealsign=0 und rf.yearmonth in(200811,200901,200903,200804,200805,200806,200807)
und rf.customerid=1000052545) ein linker äußerer Join (wählen Sie xe.employeeid,xe.name aus xt_employee xe) b auf a.tollcollector=b.employeeid)
c linker äußerer Join (wählen Sie cp.chargeint,cp.customerid aus sf_chargeprotocol cp aus, wobei cp.customerid=1000052545 ist) d
auf c.customerid=d.customerid
Sie können sehen, dass wir in diesem Beispiel zunächst die benötigten Datensätze aus jeder Tabelle unter Verwendung nahezu derselben Bedingungen herausfiltern und die Datensätze dann zusammenführen. Bei der tatsächlichen Verwendung habe ich festgestellt, dass dies fast 60-mal schneller ist als eine direkte Linkabfrage. Obwohl es hässlich und schwer zu lesen ist, löst es das SQL-Leistungsproblem. Das verwendete Prinzip besteht immer noch darin, zuerst den Bereich einzuschränken und dann eine Verbindungsabfrage durchzuführen. Wenn wir eine Verbindung herstellen und dann filtern, entspricht dies dem Zusammenführen zweier Tabellen und dem anschließenden Abrufen von Daten basierend auf den Bedingungen.