sqlite的count

以此表为例:

CREATE TABLE MyData (
    PID        INTEGER     PRIMARY KEY,
    GUID       INTEGER,
    DTime       DATETIME,
    Value      DOUBLE,
    Flag       INTEGER
);
CREATE UNIQUE INDEX MyData_TimeGUID ON MyData (
    DTime,
    GUID
);
CREATE INDEX MyData_Flag ON MyData (
    Flag
);

备注:“explain query plan SQL语句”可以查看SQL具体是如何解析执行的。

1、不像MySQL,SQLite的count操作没有内部优化,是一个简单遍历的过程,由于遍历索引的速度比表的速度快数量级倍,所以是不是用count(*)没关系,但不要试图以没有索引的字段为条件执行count;
2、count时,假如上表还单独为DTime和GUID分别建立了索引,则如果以DTime+GUID为条件,查询时只使用GUID索引(可以用explain查看),如果每种GUID值的条数较少,则还算比较快,但如果每种条数很多(也就是说GUID值种数很少),则count就已经会非常耗时,因为它拿索引命中后,仍要到数据中去比对DTime;也就是说,如果程序需要以DTime+GUID为条件执行
count,则不要单独为DTime和GUID分别建立索引,因为它们会阻止SQL解释器直接使用联合索引MyData_TimeGUID;
3、即使单独以DTime或GUID为条件查询,SQL解释器依然会使用联合索引MyData_TimeGUID,并且是有效的,也就是说联合索引MyData_TimeGUID既能作用于其含有的所有字段,也能单独作用于其含有的单独字段;

补:以上三条后来发现,原因是DTime是datetime类型,而datetime类型在sqlite内部是字符串存的,而GUID是整数类型,当以DTime+GUID为条件查的时候,整数类型的索引效率更高,所以它优先选用了GUID索引;如果DTime也是整数类型,则就不存在上述问题;


4、如果索引字段的内容值重复率很高,当数据量很大的时候,count依然会非常耗时,因为虽然命中很快,但后续时间都耗在了累加上;所以,在建立索引的时候一方面要考虑业务需求,另一方面要考虑数据特点;

5、使用select * from sqlite_master where type='index'仔细查看表上的所有索引,以免有你不知道的其它索引对你的索引起了反面的影响;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值