sqlite在左连接中使用了错误的索引

时间:2014-09-25 11:25:29

标签: sql performance sqlite indexing

我正在使用左连接加入两个表:

第一个表很简单

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使用另一个索引吗?

2 个答案:

答案 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的类型。如果它与主键的类型不同,则不会使用索引(可能)。