优化Sqlite自连接

问题描述 投票:0回答:1

帮助我优化我的sqlite查询

表格:

CREATE TABLE links (
    c   INTEGER NOT NULL,
    position    INTEGER NOT NULL,
    key_id INTEGER  REFERENCES keys(id),
    PRIMARY KEY(c, position, key_id)
) WITHOUT ROWID;

查询

select c_1.* from links c_1 
join links c_2 on c_1.key_id = c_2.key_id and c_2.position > c_1.position
join links c_3 on c_1.key_id = c_3.key_id and c_3.position > c_2.position
join links c_4 on c_1.key_id = c_4.key_id and c_4.position > c_3.position
where c_1.c = unicode('A') 
and c_2.c = unicode('p')
and c_3.c = unicode('i')
and c_4.c = unicode('x')

这个想法是通过索引一个单词('key_id')的每个稍后('c')来实现子字符串搜索。我试图回答以下要求:给我所有包含A且位置大于p且具有A且位置大于i并且相同的单词用pi。上面的查询应与以下单词匹配:

  • Apix
  • ToastApizx
  • xpAoopiox

换句话说,我正在尝试优化以下查询:

x

查询计划如下所示:select * from links where key like '%A%p%i%x%'

样本结果

enter image description here

在此示例中,它找到了三个键。稍后,我将其映射到单词,并能够显示它找到的前缀是什么。

c|position|key_id ----------------- 65 1 121 65 1 2292 65 1 3919 65 1 3923 65 1 3925 65 1 3933 65 1 3946 65 1 4375 65 1 4375 65 1 4375 65 1 4375 中有240,076行的时间,执行需要2秒。如何使其运行更快?

sqlite inner-join self-join
1个回答
0
投票

您的主键索引在links上,但是在您的查询中,您的c, position, key_idWHERE测试将ON等同,将c等同,并将position等同。这意味着索引中的key_id无法使用。

key_id(添加了强调):

然后,如果索引的初始列(列a,b等)以WHERE子句形式出现,则可以使用索引。索引的初始列必须与=INIS运算符一起使用。 [使用的最右边的列可以使用不等式。对于使用的索引的最右边的列,最多可能有两个不等式必须将列的允许值夹在两个极端之间。] >

正如您所发现的,将the documentation检查中的>切换为position会大大提高速度-使用三个相等性检查意味着整个索引可用于查找匹配的行。

如果您重新创建表时,其PK中的列顺序不同-至=,或者以该顺序添加具有这三列的新索引,您应该会看到一个改进,因为这样可以使用整个索引查找要联接的行,而不仅仅是索引的一部分,因为它遵循以下约束:除了最右边的列之外,所有列都使用相等性测试。

© www.soinside.com 2019 - 2024. All rights reserved.