2016-10-23 1 views
1

Mit folgendem Setup mit:SQLite GROUP BY auf das Ergebnis der Vereinigung nicht Indizes der konstituierenden Tabellen

> CREATE TABLE test_table1(test_col INT NOT NULL); 
> CREATE TABLE test_table2(test_col INT NOT NULL); 
> CREATE INDEX test_index1 ON test_table1(test_col); 
> CREATE INDEX test_index2 ON test_table2(test_col); 

eine GROUP BY auf einer Unterabfrage Doing eine einzelne Tabelle Referenzierung verwendet seinen Index, wie erwartet:

> EXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM test_table1) GROUP BY test_col; 
selectid order from detail 
-------- ----- ---- ------------------------------------------------------- 
0   0  0  SCAN TABLE test_table1 USING COVERING INDEX test_index1 

Aber die gleiche GROUP BY auf der Vereinigung von zwei Tabellen, von denen beide einen Index haben, ergibt zwei vollständige Tabellenscans:

> EXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM test_table1 UNION ALL SELECT * FROM test_table2) GROUP BY test_col; 
selectid order from detail 
-------- ----- ---- --------------------------------------- 
2   0  0  SCAN TABLE test_table1 
3   0  0  SCAN TABLE test_table2 
1   0  0  COMPOUND SUBQUERIES 2 AND 3 (UNION ALL) 
0   0  0  SCAN SUBQUERY 1 
0   0  0  USE TEMP B-TREE FOR GROUP BY 

Zumindest in der Theorie sollte SQLite die Gruppierung auf jede Tabelle in der Union mit dem Index dieser Tabelle anwenden können, dann die Ergebnisse in ein Gesamtergebnis zusammenführen, richtig? Gibt es eine Möglichkeit, darauf hinzuweisen, dass es dies tun sollte? Ich habe versucht, INDEXED BYs ohne Erfolg hinzuzufügen.

+0

Verwenden Sie 'select *' nicht mit 'group by'. Es macht einfach keinen Sinn, semantisch. –

Antwort

1

Es könnte möglich sein, dass die Datenbank die Gruppierung auf jede Tabelle anwenden könnte - theoretisch. Das Problem ist jedoch, dass die Software in der Lage sein muss zu beweisen, dass diese Transformation immer gültig ist.

Mit der aktuellen Optimiererimplementierung kann diese Abfrage nicht abgeflacht werden, da sie rule 17 verletzen würde.