加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么SQLite在添加JOIN时拒绝使用可用索引?

发布时间:2020-12-12 18:58:11 所属栏目:百科 来源:网络整理
导读:这与 Why is SQLite refusing to use available indexes?有关 创建数据库的查询是: CREATE TABLE foo(id TEXT);CREATE INDEX `foo.index` ON foo(id);CREATE TABLE bar(id TEXT);CREATE INDEX `bar.index` ON bar(id);CREATE VIEW baz AS SELECT id FROM fo
这与 Why is SQLite refusing to use available indexes?有关

创建数据库的查询是:

CREATE TABLE foo(id TEXT);
CREATE INDEX `foo.index` ON foo(id);
CREATE TABLE bar(id TEXT);
CREATE INDEX `bar.index` ON bar(id);
CREATE VIEW baz AS SELECT id FROM foo UNION ALL SELECT id FROM bar;
CREATE TABLE bam(id TEXT,value TEXT);

INSERT INTO foo VALUES('123');
INSERT INTO foo VALUES('1123');
INSERT INTO foo VALUES('2123');
INSERT INTO foo VALUES('3123');

INSERT INTO bar VALUES('44123');
INSERT INTO bar VALUES('441123');
INSERT INTO bar VALUES('442123');
INSERT INTO bar VALUES('443123');

EXPLAIN QUERY PLAN SELECT * FROM baz LEFT JOIN bam ON baz.id = bam.id WHERE baz.id IN(‘123′,’234’);是:

SCAN TABLE foo (~1000000 rows)
SCAN TABLE bar (~1000000 rows)
COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)
SCAN SUBQUERY 1 (~2000000 rows)
EXECUTE LIST SUBQUERY 4
SEARCH TABLE bam USING AUTOMATIC COVERING INDEX (id=?) (~7 rows)

编辑:有趣的是,如果我执行EXPLAIN QUERY PLAN SELECT * FROM(SELECT * FROM baz WHERE baz.id IN(‘123′,’234’))AS t LEFT JOIN bam ON t.id = bam.id;它仍然没有使用索引,但如果我做EXPLAIN QUERY PLAN SELECT * FROM baz WHERE baz.id IN(‘123′,’234’);它确实.到底是怎么回事?

为什么不使用foo和bar上的索引?它确实使用没有JOIN部分的索引,如链接问题中所示.

SQL小提琴:http://sqlfiddle.com/#!7/32af2/14(使用WebSQL)

解决方法

不使用索引,因为它们不是必需的;他们不会加快查询速度.

在SQLite中,连接被实现为嵌套循环连接,也就是说,数据库遍历一个表的所有记录,并且对于每个记录,查找另一个表中的匹配记录.
只有第二个表中的查找才需要索引;只是浏览第一个表的所有记录不需要索引.

使用内部联接,查询优化器可以选择循环中的外部表或内部表(如果只有一个表具有索引,则应该是内部表).
但是,使用左外连接时,没有选择,左表必须是外表.

要优化左外连接,(仅)右侧的表需要索引.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读