查询时间突然增加

Query time suddenly increased

我有 MariaDB 10.1.14,很长一段时间我都在毫无问题地执行以下查询(大约需要 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 秒。
这是解释:

这些是交易的所有索引table:

查询时间突然增加是什么原因?我怎样才能减少它?

如果您向 table 添加更多数据,查询时间将会增加。

但是您可以做一些事情来提高性能。

  • ( transaction_type, transaction_status, created_at) 创建复合索引
  • 从您的字段中删除 DATE() 函数(或任何函数),因为那样不允许引擎使用索引。 CURRENT_DATE 是一个常数,所以没有关系,但不是必需的,因为已经 return DATE
    • 如果 created_at 不是您可以使用的日期
    • created_at >= CURRENT_DATE and created_at < CURRENT_DATE + 1
    • 或创建一个不同的字段以仅保存日期部分。

我不知道是什么让您的查询变慢了。更多数据?碎片化?新数据库版本?

然而,令我惊讶的是,并没有真正支持查询的索引。您应该有一个从具有最高基数的列开始的复合索引(日期?好吧,您可以尝试不同的列顺序并查看 DBMS 为查询选择哪个索引)。

create index idx1 on transactions(created_at, transaction_type, transaction_status);

如果 created_at 包含日期部分,那么您可能希望创建一个计算列 created_on 只包含日期和索引。

您甚至可以将此索引扩展为覆盖索引(where 子句字段后跟 group by 子句字段后跟 select 子句字段):

create index idx2 on transactions(created_at, transaction_type, transaction_status,
                                  transaction_currency, transaction_total);

+1 来自@JuanCarlosOropeza 的回答,但您可以进一步了解索引。

ALTER TABLE transactions ADD INDEX (
  transaction_type,
  transaction_status,
  created_at,
  transaction_currency,
  transaction_total
);

正如@RickJames 在评论中提到的,列的顺序很重要。

  • 首先,相等比较中的列
  • 接下来,您可以索引 一个 用于范围比较(除了相等性之外的任何东西)或 GROUP BY 或 ORDER BY 的列。你有范围比较和 GROUP BY,但你只能得到索引来帮助其中之一。
  • 最后,查询需要的其他列,如果你觉得可以得到一个覆盖索引。

我在演示文稿中描述了有关索引设计的更多细节 How to Design Indexes, Really (video: https://www.youtube.com/watch?v=ELR7-RdU9XU)。

您可能受困于 "using temporary",因为您有范围条件以及引用不同列的 GROUP BY。但是你至少可以通过这个技巧来消除"using filesort":

...
GROUP BY 
    transaction_currency
ORDER BY NULL

假设查询结果 return 中的行排序对您来说并不重要。