예를 들어 다음을 고려 잘못된 쿼리 계획을 선택합니다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) 여기서 쿼리 계획을 돕기 위해 1000 < 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<?)
, 어쨌든 우리는 전체 테이블을 반복해야하는 이유 (첫 번째 질의에 대한) 인덱스를 사용하는 것은 의미가 없기 때문에 일반 SCAN 테이블에 보인다 더 효율적으로 정확히 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) –