Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 为什么SQLite不使用索引来查询我的多对多关系表?_Performance_Sqlite_Indexing_Many To Many_Sql Execution Plan - Fatal编程技术网

Performance 为什么SQLite不使用索引来查询我的多对多关系表?

Performance 为什么SQLite不使用索引来查询我的多对多关系表?,performance,sqlite,indexing,many-to-many,sql-execution-plan,Performance,Sqlite,Indexing,Many To Many,Sql Execution Plan,我已经有一段时间没有编写代码了,我以前从未使用过SQLite,但多对多关系曾经是如此基本,必须有一种方法使它们快速 这是我的数据库的抽象版本: CREATE TABLE a (_id INTEGER PRIMARY KEY, a1 TEXT NOT NULL); CREATE TABLE b (_id INTEGER PRIMARY KEY, fk INTEGER NOT NULL REFERENCES a(_id)); CREATE TABLE d (_id INTEGER PRIMARY K

我已经有一段时间没有编写代码了,我以前从未使用过SQLite,但多对多关系曾经是如此基本,必须有一种方法使它们快速

这是我的数据库的抽象版本:

CREATE TABLE a (_id INTEGER PRIMARY KEY, a1 TEXT NOT NULL);
CREATE TABLE b (_id INTEGER PRIMARY KEY, fk INTEGER NOT NULL REFERENCES a(_id));
CREATE TABLE d (_id INTEGER PRIMARY KEY, d1 TEXT NOT NULL);
CREATE TABLE c (_id INTEGER PRIMARY KEY, fk INTEGER NOT NULL REFERENCES d(_id));
CREATE TABLE b2c (fk_b NOT NULL REFERENCES b(_id), fk_c NOT NULL REFERENCES c(_id), CONSTRAINT PK_b2c_desc PRIMARY KEY (fk_b, fk_c DESC), CONSTRAINT PK_b2c_asc UNIQUE (fk_b, fk_c ASC));
CREATE INDEX a_a1 on a(a1);
CREATE INDEX a_id_and_a1 on a(_id, a1);
CREATE INDEX b_fk on b(fk);
CREATE INDEX b_id_and_fk on b(_id, fk);
CREATE INDEX c_id_and_fk on c(_id, fk);
CREATE INDEX c_fk on c(fk);
CREATE INDEX d_id_and_d1 on d(_id, d1);
CREATE INDEX d_d1 on d(d1);
我已经输入了我能想到的任何索引,只是为了确保它是合理的,但不是问题,因为数据是只读的。但在这个问题上

SELECT count(*) 
FROM  a, b, b2c, c, d 
WHERE a.a1 = "A" 
    AND a._id = b.fk 
    AND b._id = b2c.fk_b 
    AND c._id = b2c.fk_c 
    AND d._id = c.fk 
    AND d.d1 ="D";
关系表b2c不使用任何索引:

0|0|2|SCAN TABLE b2c
0|1|1|SEARCH TABLE b USING INTEGER PRIMARY KEY (rowid=?)
0|2|0|SEARCH TABLE a USING INTEGER PRIMARY KEY (rowid=?)
0|3|3|SEARCH TABLE c USING INTEGER PRIMARY KEY (rowid=?)
0|4|4|SEARCH TABLE d USING INTEGER PRIMARY KEY (rowid=?)
查询大约要慢两个数量级才能使用。有没有办法让SQLite在b2c上使用索引


谢谢

在嵌套循环联接中,最外层的表不使用联接的索引,因为数据库只是遍历所有行

为了能够对联接使用索引,索引和其他列必须具有相同的类型,这通常意味着两个列必须具有相同的类型

将b2c列的类型更改为整数

如果a1或d1上的查找是非常有选择性的,那么使用a或d作为最外层的表可能是有意义的,这样就可以允许为过滤器使用索引。 试着跑步


如果没有帮助,您可以使用或强制加入订单。

谢谢@CL。我在真实数据库中运行了分析。但是关系表仍然不使用索引。它位于查询计划解释的第二行,我假设这意味着它不是最外层的循环。第一行显示索引的用法。好的,我试过了。结果是神秘的。。。使用交叉连接可以更改循环的位置,但不能更改索引的使用。当我使用索引时,SQLITE的行为各不相同:对于PK_b2c_desc SQLITE,没有返回这样的索引。与giberish和b_id_和_fk相同。对于sqlite_autoindex_b2c_1,sqlite未返回任何查询解决方案。SQLITE似乎忽略了表b2c的CREATETABLE语句中的index命令,并创建了自己的索引SQLITE_autoindex_b2c_1。但不知何故,它无法使用它;我忽略了b2c中缺少的类型。谢谢@CL。终于成功了!我永远不会独自解决这个问题!