請考慮下面的例子:sqlite的選擇錯誤的查詢計劃
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
WITH RECURSIVE
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
INSERT INTO t1(a,b) SELECT x, x FROM cnt;
CREATE INDEX t1b ON t1(b);
此查詢創建表而不ROWID列並插入值(x,x),其中 X < 2000年爲了幫助查詢規劃允許運行分析。
ANALYZE;
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE b BETWEEN 500 AND 2500;
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE b BETWEEN 2900 AND 3000;
在這兩種情況下的輸出是:0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1b (b>? AND b<?)
然而,沒有必要使用索引(第一個查詢),理由是反正我們通過整個表進行迭代,所以普通掃描表似乎效率更高。究竟這種方式與rowid的工作表:
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a, b);
WITH RECURSIVE
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
INSERT INTO t1(a,b) SELECT x, x FROM cnt;
CREATE INDEX t1a ON t1(a);
ANALYZE;
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500;
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000;
在這種情況下,輸出將是:0|0|0|SCAN TABLE t1
和0|0|0|SEARCH TABLE t1 USING INDEX t1a (a>? AND a<?)
所以,可能有人解釋查詢規劃如何優化查詢,而不ROWID表?
我真的不明白爲什麼有些人喜歡DV這個漂亮的問題。他們甚至讀過或理解這個問題嗎?我upvoted抗衡;) –