【问题标题】:How to speed up SQL query with date GROUP BY?如何使用日期 GROUP BY 加速 SQL 查询?
【发布时间】:2017-04-22 18:41:12
【问题描述】:

我有一个名为 table1 的普通 SQLite 数据库表,它有 7 列,当然还有一个 rowid。第一列是 custom_id 数字,第二列是格式 YYYY-MM-DD 的日期,其他 5 列是实数数据列。数据库大约有10M行,custom_id和date列都有索引。

我想做的是加快以下查询:

SELECT date,max(data1) AS maximum
FROM table1
WHERE custom_id = '1123' AND data1 <> 'NaN'
GROUP BY strftime('%Y-%m', date)

我想为每个年月组合的 custom_id 1123 找到最大正确(不是 NaN)data1 值。上面的代码实际上运行良好,但第一次运行查询持续 10 秒,但第二次运行不到 1 秒,这对我来说没问题。我使用 PHP 在我的家用 PC Apache 服务器上运行查询。我认为 Apache 使用了一些缓存来解释差异。

但问题是,如何加快首次运行性能?我还有很多其他的 custom_id:s 要查询,不是所有的都可以缓存!我需要更多索引吗?另一种查询?

【问题讨论】:

  • 你为什么有datedate1
  • @GordonLinoff - date (d-a-t-e) 和 data1 (d-a-t-a) 这是一个数值。
  • @GordonLinoff 我有日期和 5 个数据列 data1、data2、data3、data4 和 data5。我是否必须为每个数据列创建 5 个索引? table1(custom_id, data1), table1(custom_id, data2)... 这会大大增加文件大小。目前文件大小约为 900 兆字节。如果我必须使用更多索引,我不想超过 2 GB。

标签: sql performance sqlite date indexing


【解决方案1】:

我们将创建一个支持以下操作的索引:

  1. 检索特定客户的记录
  2. 按月汇总

无法创建以下索引,因为strftime 不是确定性函数

create index table1_ix on table1 (custom_id,strftime('%Y-%m', date));

索引表达式中禁止使用非确定性函数

所以我们将使用substr(date,1,7)而不是strftime('%Y-%m', date)

create index table1_ix on table1 (custom_id,substr(date,1,7));

查询应相应更改

select      substr(date,1,7), max(data1) as maximum
from        table1
where       custom_id = '1123' 
        and data1 <> 'NaN'
group by    substr(date,1,7)

【讨论】:

  • 我得到以下错误:SQLite3::query(): Unable to prepare statement: 11, malformed database schema (table1_ix2) - near "(": syntax error 但是,根据SQLitebrowser创建索引成功。
  • 你为什么要创建第一个索引?!
  • 很抱歉,我不明白您所说的第一个索引是什么意思。我运行了这个create index table1_ix on table1 (custom_id,substr(date,1,7));,然后 SQlitebrowser 创建了它。
  • 不,你跑了create index table1_ix on table1 (custom_id,strftime('%Y-%m', date));,我知道是因为我不小心将索引名称保留为table1_ix2(我已经编辑了答案并更改了它)
  • 好的,现在我明白了。但是,我很确定索引是正确的(这是一个捕获)imgur.com/a/2JPuP。结果就是这个Warning: SQLite3::query(): Unable to prepare statement: 11, malformed database schema (table1_ix) - near "(": syntax error in
【解决方案2】:

我猜这就是你想要的:

SELECT strftime('%Y-%m', date), max(data1) AS maximum
FROM table1
WHERE custom_id = 1123 AND data <> 'NaN'
GROUP BY strftime('%Y-%m', date)

table1(custom_id, date) 上的索引开始。

【讨论】:

  • 日期索引与此查询无关
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多