此查询耗时太长(800 mhz cpu上超过15000条记录):
select count(*) from events where millis > date("now", "start of month")
该字段定义为millis INT
,当我运行查询(或我提出的任何其他变体)时,sqlite似乎对它所比较的每条记录进行日期转换。我用strace看到了:
read(3, "\r\0\0\0\21\0H\0\3\310\3\220\3X\3 \2\350\2\260\2x\2@\2\10\1\320\1\230\1`"..., 1024) = 1024
gettimeofday({1399595165, 605812}, NULL) = 0
gettimeofday({1399595165, 609833}, NULL) = 0
gettimeofday({1399595165, 611851}, NULL) = 0
gettimeofday({1399595165, 618546}, NULL) = 0
gettimeofday({1399595165, 623135}, NULL) = 0
gettimeofday({1399595165, 626291}, NULL) = 0
gettimeofday({1399595165, 634558}, NULL) = 0
gettimeofday({1399595165, 636463}, NULL) = 0
gettimeofday({1399595165, 638986}, NULL) = 0
gettimeofday({1399595165, 669426}, NULL) = 0
gettimeofday({1399595165, 675431}, NULL) = 0
...
And it keeps running
¿有没有一种有效的方法来计算属于当天的记录,只将“现在”转换为一次int并在此之后进行简单的数学运算?
编辑:正如CL指出的那样,只需通过预先计算日期即可。无需将其强制转换为int。以下工作更快(没有日期比较):
select date( "now", "-1 day");
2014-05-08
sqlite> select count(millis) from events where millis > "2014-05-08";
1177
另一件大幅提升性能的事情是在列上创建一个索引,就像在任何其他数据库引擎上一样。不知道为什么我认为SQLite不支持它们。
仅供记录:
sqlite> create index ievemts_millis on events (millis);
sqlite> select date( "now", "-1 day");
2014-05-08
sqlite> select count(millis) from events where millis > "2014-05-08";
1177
答案 0 :(得分:1)
对于像这样的简单值,您可以使用两个查询:
SELECT date('now', 'start of month');
SELECT COUNT(*) FROM events WHERE millis > ?;
(在应用程序的代码中计算毫秒值可能更容易。)
最近足够多的SQLite版本只评估date
函数一次。