1

Es gibt eine Abfrage, die vollständige Tabelle scannt, gibt es 5 Millionen Datensätze, kostet es etwa 60s. Wie kann ich das optimieren? Ich habe versucht, Speichermodus von SQLite zu verwenden, in der Theorie sollte dies schneller sein, da die gesamte Datenbank in Memroy gespeichert ist. Es kostet jedoch fast die gleiche Zeit. Tabellenschema wie folgt aus:Warum im Speichermodus donot beschleunigen in sqlite

CREATE TABLE tbl0(estimateid int, seq int, field1 int NULL, field2 int NULL, field3 int NULL, field4 int NULL); 
CREATE INDEX tbl0_idx on tbl0(estimateid); 
CREATE TABLE tbl1(seq int, companyid int, field1 int NULL, field2 int NULL, field3 int NULL, field4 int NULL, field5 int NULL); 
CREATE INDEX tbl1_idx on tbl1(seq); 
CREATE TABLE tbl2(symbolid int, relatedcompanyid int, value char(64), field1 int NULL, field2 int NULL, field3 int NULL, field4 int NULL, field5 int NULL); 
CREATE INDEX tbl2_idx on tbl2(relatedcompanyid); 

und dies ist Abfrage, Abfrage, die drei Tabellen verbinden müssen:

>explain query plan select tbl0.estimateid, tbl1.seq, tbl1.companyid, tbl2.value from tbl0, tbl1, tbl2 where tbl0.seq = tbl1.seq and tbl1.companyid = tbl2.relatedcompanyid; 
0|0|1|SCAN TABLE tbl1 
0|1|2|SEARCH TABLE tbl2 USING INDEX tbl2_idx (relatedcompanyid=?) 
0|2|0|SEARCH TABLE tbl0 USING AUTOMATIC COVERING INDEX (seq=?) 

Wie diese Abfrage beschleunigen? Scheint es unvermeidlich, dass ein Tisch vollständig gescannt wird. Jede Tabelle enthält ca. 5 Millionen Datensätze, diese Abfrage kostet sehr lange Zeit (mehrere Minuten). Wenn ich db im Speicher ablege, benutze diese # sqlite3: memory :, es macht keinen Unterschied in der Geschwindigkeit. Hilfe wird sehr geschätzt.

+0

Um dies zu optimieren, scannen Sie nicht 5 Millionen Datensätze. –

Antwort

1

A vollständiger Index-Scan (Typ: Index) wird nach der Dokumentation ist der 2. schlimmstmögliche Ausführungsplan nach einem vollständigen Tabellenscan, die Sie ausgewählt.

Vollständige Tabelle Scan ist ressourcenintensive Operation für die DB, und es gibt keine Magie hinter den Kulissen, wenn Sie Ihren Speicher, CPU-Geschwindigkeit steigern, wird die Tabelle indizieren, wird die Anzahl der Datensätze usw. reduzieren. Wenn Sie alles in den Speicher verschoben haben, ist Ihnen eine drastische Geschwindigkeitserhöhung aufgefallen.

Sie sollten versuchen, dies zu vermeiden und die bessere Abfrage zu machen oder die DB- und Tabellenstrukturen zu optimieren. Bitte, Referenz EXPLAIN QUERY PLAN und Query Planning für weitere Informationen über die Ausführung Ihres SQL und wie es optimiert werden kann.

Es ist schwer, mehr zu sagen, und um genauer zu sein, wie in der ursprünglichen Frage, die Sie nicht die DB-Strukturen zur Verfügung gestellt haben, die Eigenschaften Ihrer Daten, Ihre Anfrage usw.

+0

Können Sie mir sagen, wie Sie diese Join-Abfrage oben beschleunigen können? Scheint, dass eine Tabelle vollständig gescannt wird, wie kann ich bestimmen, welche Tabelle gescannt wird, Wenn ich kann, könnte ich Aufzeichnungen von tbl2 reduzieren, und sqlite sagen, tbl2, tbl1 und tbl0 zu scannen. Auf diese Weise wird Abfrage schneller sein, denke ich. – wushiqi

+0

@wushiqi, in Ihrem Fall, würde ich empfehlen, richtig Indizes für Ihre Tabellen zu verwenden, gerade jetzt - es macht den vollständigen Tabellenscan, nur um den Wert zu finden - es muss die gesamten Daten suchen. Indizes sind spezielle Nachschlagetabellen, die die Datenbanksuchmaschine verwenden kann, um den Datenabruf zu beschleunigen. Kurz gesagt: Spalten, die für Tabellen-Joins verwendet werden, sind normalerweise die perfekten Kandidaten, ebenso wie Spalten, die häufig als Suchkriterium verwendet werden. – Farside

+0

Ich habe Index wie oben gezeigt erstellt. Können Sie mir sagen, wie Sie das optimieren können? Jetzt enthält jede Tabelle 5 Millionen Datensätze, und diese Abfrage kostet 300s und produziert insgesamt 300.000.000 Datensätze. Ich sehne mich sehr nach Optimierung. Danke vielmals!!! – wushiqi

0

Ihre Datenbank ist nicht im Speicher ; Du hast etwas falsch gemacht. Ich habe ein Programm erstellt, um 5 Millionen Datensätze in ein anderes speicherinternes Datenbanksystem zu laden, und es dauerte weniger als 800 Millisekunden für einen vollständigen sequenziellen Scan. Selbst wenn SQLite nur halb so schnell ist wie das In-Memory-Datenbanksystem, das ich verwendet habe, sollte es nur ein oder zwei Sekunden dauern.

Eine andere Möglichkeit ist, dass Sie in die Konsole schreiben, nachdem Sie jede Zeile abgerufen oder eine andere Logik ausgeführt haben, die die gesamte Langsamkeit verursacht.