我发现查询计划在w / o和w / keys之间改变。
CREATE TABLE `data` (
`name` TEXT,
`value` NUMERIC,
PRIMARY KEY(`name`)
) WITHOUT ROWID;
CREATE TABLE `ranges` (
`begin` TEXT,
`end` TEXT,
);
explain query plan select distinct t1.name as name from data t1, ranges t2 where t1.name between t2.begin and t2.end order by name;
"0" "0" "1" "SCAN TABLE ranges AS t2"
"0" "1" "0" "SEARCH TABLE data AS t1 USING PRIMARY KEY (name>? AND name<?)"
"0" "0" "0" "USE TEMP B-TREE FOR DISTINCT"
如果我将开始和结束定义为键,
CREATE TABLE `ranges` (
`begin` TEXT,
`end` TEXT,
PRIMARY KEY(`begin`,`end`)
);
查询计划更改为以下内容。
"0" "0" "0" "SCAN TABLE data AS t1"
"0" "1" "1" "SEARCH TABLE ranges AS t2 USING COVERING INDEX sqlite_autoindex_ranges_1 (begin<?)"
第一个查询计划更好,因为在我的情况下,数据表比范围大得多。
我读了https://sqlite.org/optoverview.html。它表示连接顺序是由sqlite的默认选择(没有分析结果)定义的。添加这些键是否会更改默认选项?有没有其他技巧让SQLite使用第一个查询计划而不提供统计数据?
另外,默认选择是否未更改?以后会改变吗?我用3.22。
我还注意到,如果我不使用order by和distinct,它总是使用第一个计划
explain query plan select t1.name as name from data t1, ranges t2 where t1.name between t2.begin and t2.end;
"0" "0" "1" "SCAN TABLE ranges AS t2"
"0" "1" "0" "SEARCH TABLE data AS t1 USING PRIMARY KEY (name>? AND name<?)"