SQLite 3基于UnixEpoch优化时间条件查询问题
让我一步步帮你理清这些问题,从根源上解决查询失效和速度慢的问题:
1. 方法3为啥没生效?问题出在epochTime的格式和时间偏移写法
先看你生成epochTime的代码:
now = datetime.datetime.now() epochTime = now.strftime("%s100")
这里%s会输出秒级Unix时间戳的字符串,拼接100后得到的是类似1700000000100的字符串。如果你的table1里epochTime存的是字符串类型,SQLite做数值比较时会按字符顺序判断,完全不是你想要的数值大小对比,这就会导致条件失效。
另外,你用select datetime('now','-68400')是错的:datetime的偏移参数,'-68400'默认是秒,68400秒才19小时,根本不是5天!而且datetime返回的是YYYY-MM-DD HH:MM:SS格式的字符串,和你的epochTime格式完全不搭,这也是方法3查不到数据的核心原因。
2. 方法2为啥比方法1慢2秒?索引缺失是关键
方法1只靠rowid过滤,而SQLite的rowid本身自带主键索引,查询时直接走索引,速度快得飞起。但方法2加了timestamp的过滤条件:
- 如果
timestamp字段没建索引,SQLite得先找出所有rowid%200=0的行,再挨个检查timestamp是否符合要求,额外多了一轮扫描计算,自然变慢; - 就算有索引,你嵌套子查询的写法可能让SQLite优化器没法高效利用索引,进一步拖慢速度。
3. 正确的Unix Epoch查询写法
首先得把epochTime的存储和生成逻辑掰正:
先修正Python里的epochTime生成
要生成适配Highcharts的毫秒级时间戳,别用字符串拼接,直接生成整数更靠谱:
# 方法1:用time模块 import time epochTime = int(time.time() * 1000) # 方法2:用datetime from datetime import datetime now = datetime.now() epochTime = int(now.timestamp() * 1000)
把这个整数存入数据库,后续查询就不会有类型问题了。
对应的SQL查询语句
如果epochTime是毫秒级整数,查询最近5天数据的正确写法是:
SELECT epochTime, x FROM ( SELECT rowid, epochTime, x FROM table1 WHERE rowid % 200 = 0 AND epochTime > (strftime('%s', 'now', '-5 day') * 1000) ) ORDER BY rowid ASC
解释下:
strftime('%s', 'now', '-5 day')会返回5天前的秒级Unix时间戳整数;- 乘以1000转成毫秒级,和你存的epochTime格式完全匹配;
- 纯数值对比,SQLite处理起来效率很高。
你也可以简化掉嵌套子查询,SQLite优化器通常能处理好:
SELECT epochTime, x FROM table1 WHERE rowid % 200 = 0 AND epochTime > (strftime('%s', 'now', '-5 day') * 1000) ORDER BY rowid ASC
4. 怎么让时间条件查询也变快?加索引!
给epochTime建个索引,就能让时间过滤的速度大幅提升:
CREATE INDEX idx_table1_epochtime ON table1(epochTime);
有了索引后,SQLite可以快速定位到符合时间条件的行,再结合rowid%200=0的过滤,速度就能接近方法1了。
总结一下:核心问题是epochTime的格式错误+时间偏移写法不对,修正后配合索引,就能兼顾查询速度和准确性啦~
内容的提问来源于stack exchange,提问作者Subbyy

