目录
- 先来唠唠嗑吧~
- 那一探究竟吧!
- 表结构及索引信息
- 我的查询场景
- 到底命中什么索引了?
- 简单小结下~
先来唠唠嗑吧~
在使用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语句相关索引!