查询时间突然增加
我有MariaDB的10.1.14,很长一段时间我做没有问题下面的查询(它tooks约3秒):查询时间突然增加
SELECT
sum(transaction_total) as sum_total,
count(*) as count_all,
transaction_currency
FROM
transactions
WHERE
DATE(transactions.created_at) = DATE(CURRENT_DATE)
AND transaction_type = 1
AND transaction_status = 2
GROUP BY
transaction_currency
突然间,我不知道到底为什么这个查询需要大约13秒。
这是EXPLAIN:
什么是突如其来的查询时间增加的原因?我该如何减少它?
+1从@JuanCarlosOropeza回答,但你可以去索引稍微进一步。
ALTER TABLE transactions ADD INDEX (
transaction_type,
transaction_status,
created_at,
transaction_currency,
transaction_total
);
As @RickJames在评论中提到,列的顺序很重要。
- 首先,列相等比较
- 接下来,可以说被用于范围比较(这是除了任何平等)索引一个列或GROUP BY或ORDER BY。你有范围比较和GROUP BY,但你只能得到索引来帮助其中的一个。
- 最后,查询所需的其他列,如果您认为可以获得覆盖索引。
我在我的演示文稿How to Design Indexes, Really(视频:https://www.youtube.com/watch?v=ELR7-RdU9XU)中介绍了有关索引设计的更多详细信息。
由于您有一个范围条件,并且还有一个GROUP BY引用了不同的列,所以您可能会陷入“使用临时”状态。但你至少可以通过这一招消除“使用文件排序”。
...
GROUP BY
transaction_currency
ORDER BY NULL
假设,这不是对你很重要,其订购查询结果的行中返回
如果您要向表中添加更多数据,查询时间将会增加。
但是你可以做一些事情来提高性能。
- 创建
(transaction_type, transaction_status, created_at)
- 从您的领域
DATE()
功能(或功能)的综合指数,因为不允许引擎使用索引。CURRENT_DATE
是一个常数所以无所谓,但没有必要,因为已经返回DATE
- 如果
created_at
心不是日期可以使用 created_at >= CURRENT_DATE and created_at < CURRENT_DATE + 1
- 或创建一个不同的领域仅保存日期部分。
- 如果
你的答案在DATE()比我的问题更明确。很好解释。 –
但指数倒退。 “范围”部分('created_at')需要是最后一个。 –
@RickJames你确定吗?看起来没问题。你会建议什么? –
我不知道是什么使您的查询慢。更多数据?不成?新的数据库版本?
但是,我很惊讶地发现没有真正支持查询的索引。您应该有一个以最高基数的列开始的复合索引(日期?那么您可以尝试不同的列顺序并查看DBMS为查询选择哪个索引)。
create index idx1 on transactions(created_at, transaction_type, transaction_status);
如果created_at
包含日期的一部分,那么你可能要创建一个计算列created_on
只包含日期和索引来代替。
您可以将这个指标甚至扩展到覆盖索引(其中后面组子句领域by子句场其后SELECT子句字段):
create index idx2 on transactions(created_at, transaction_type, transaction_status,
transaction_currency, transaction_total);
日期funtion在transactions.created_at是需要时间mysql不会使用索引如果列中包含函数 –
我会说有些事情已经改变了。那么你改变了什么? – RiggsFolly
@RiggsFolly我想到了这一点,但MAYBE唯一改变的地方是,如果AWS升级Maria次要版本,但它看起来不像它的更新。 – Michael