sqlite 使用distinct时组合索引可能不是你想的那样

目录

    • 先来唠唠嗑吧~
    • 那一探究竟吧!
      • 表结构及索引信息
      • 我的查询场景
      • 到底命中什么索引了?
    • 简单小结下~

先来唠唠嗑吧~

在使用sqlite作为词条数据库查询数据,发现有的sql执行很快,有的sql执行很慢,你以为是没有走索引吗?不一定哦,可能是因为没有走那个区分度很大的索引!!!

那一探究竟吧!

众所周知,sqlite组合索引也是基于二分查询+索引表的,所以使用索引的时候,尽可能的区分度大,这样能更快的在索引表进行定位,然后拿着rowid去表里面定位数据。

表结构及索引信息

在一张表里面,我们可能会有很多索引,本次案例就是如此。如下,是我的表结构及索引信息

create table words
(
    nid        bigint(20) not null,
    key        varchar(500) default '' not null,
    enabled    tinyint(1)   default '1' not null,
    tag        varchar(255) default '' not null,
    sort       varchar(255) default '0' not null,
    parentId   varchar(255) default '0' not null,
    isFrontend tinyint(1)   default '1' not null,
    value      varchar(255) default '' not null,
    npid       bigint(20)   default '0' not null,
    language   varchar(128) default '' not null,
    trans      mediumtext,
    primary key (nid, language)
);

create index words_npid_isFrontend_index
    on words (npid, isFrontend);

create index words_npid_key_language_index
    on words (npid, key, language);

create index words_npid_parentId_index
    on words (npid, parentId);

create index words_value_tag_npid_language_index
    on words (value, tag, npid, language);


我的查询场景

根据tag、value、npid查询key的信息,于是我使用了这个语句:

select distinct key from words where value = 11 and tag = 'atrr_id' and npid = 11

到底命中什么索引了?

按照常规思路,我会根据where语句定位命中的索引,即预测是命中:words_value_tag_npid_language_index
但事实上命中了什么呢?执行下explain,看看命中了什么索引:

explain query plan select distinct key from words where value = 11 and tag = 'atrr_id' and npid = 11

在这里插入图片描述
的确和我预测的不一样呀,为什么呢?
我就想着先简化下sql语句试试,于是把distinct key直接换成了*

explain query plan select * from words where value = 11 and tag = 'atrr_id' and npid = 11

在这里插入图片描述
这下居然和我预测的索引一样诶
我再试试只查key结果呢:

explain query plan select key from words where value = 11 and tag = 'atrr_id' and npid = 11

在这里插入图片描述
还是和我预测的一样。
所以我怀疑distinct关键字,在sqlite数据库使用时,应该和mysql不一样,它会优先命中distinct后面字段的相关索引
所以我把key相关的索引删掉,再执行有distinct的语句:

explain query plan select distinct key from words where value = 11 and tag = 'atrr_id' and npid = 11

在这里插入图片描述
这下即便使用distinct关键字也能正常命中索引了!

简单小结下~

在sqlite数据库使用时,和mysql不一样,它会优先命中distinct后面字段的相关索引,如果distinct字段没有相关索引,才会走where语句相关索引!

你可能感兴趣的:(数据库,sqlite,数据库,sql)