我正在使用左连接加入两个表:
第一个表很简单
create table L (
id integer primary key
);
并且只包含少量记录。
第二个表是
create table R (
L_id null references L,
k text not null,
v text not null
);
并包含数百万条记录。
以下两个索引位于R:
create index R_ix_1 on R(L_id);
create index R_ix_2 on R(k);
这个select语句imho选择了错误的索引:
select
L.id,
R.v
from
L left join
R on
L.id = R.L_id and
R.k = 'foo';
explain query plan
告诉我select语句使用索引R_ix_2
,执行select会花费太多时间。我相信表现会很好
如果sqlite选择使用R_ix_1
,那就更好了。
我也尝试了
select
L.id,
R.v
from
L left join
R indexed by R_ix_1 on
L.id = R.L_id and
R.k = 'foo';
但这给了我Error: no query solution
。
我能做些什么让sqlite使用另一个索引吗?
答案 0 :(得分:2)
您的连接条件依赖于2列,因此您的索引应涵盖这两列:
create index R_ix_1 on R(L_id, k);
如果您仅依靠单列执行其他查询,则可以保留旧索引,但您仍需要具有此双列索引:
create index R_ix_1 on R(L_id);
create index R_ix_2 on R(k);
create index R_ix_3 on R(L_id, k);
答案 1 :(得分:1)
我想知道SQLite优化器在这种情况下是否会混淆。这会更好吗?
select L.id, R.v
from L left join
R
on L.id = R.L_id
where R.k = 'foo' or R.k is NULL;
编辑:
当然,如果列的类型相同,SQLite将只使用索引。该问题未指定l_id
的类型。如果它与主键的类型不同,则不会使用索引(可能)。