诡异的sqlite3之malformed错误(一)
现象
- 现场设备生成并插入大规模的数据,设备异常将数据库拉出来检查时,报告
malformed
错误 - sqlite3 版本 3.8.6
- 数据库文件大小 210 MB
定位问题
-
数据大小
select count(*) from DataSheet; /*结果*/ 950131
-
主键
primary key(ctype,id,DataTime)
-
复现 (SQLite Expert)
select * from DataSheet where id='000537719140' order by DataTime; /*malformed*/ select * from DataSheet where ctype=5002 and id='000537719140' order by DataTime; /*OK*/
如上所述,这两条SQL语句差异只有where子句中是否含有oad条件,为什么会如此呢,先执行如下SQL比较一二:
select * from DataSheet where id='000537719140'; /*OK*/ select * from DataSheet order by DataTime; /*malformed, 全表扫描*/
- 当where子句中有ctype,id,DataTime时命中索引(主键),此时,
order by DataTime
对符合条件的索引排序,因此,问题不复现 - 当where子句不完全匹配有ctype,id,DataTime时,未命中索引(主键),
order by DataTime
对符合条件的结果排序,实际上执行全表扫描,问题复现
- 当where子句中有ctype,id,DataTime时命中索引(主键),此时,
-
测试代码: 定位行
char * malformed = "select rowid, ctype, id, StartTime, DataTime from DataSheet;"; /*malformed*/ char * okayQuery = "select rowid, ctype, id, DataTime from DataSheet;"; /*OK*/ char * sql = okayQuery; sqlite3_prepare_v2(db, sql, strlen(