【问题标题】:Optimize MySQL query performance优化 MySQL 查询性能
【发布时间】:2016-06-29 16:50:16
【问题描述】:

我的解决方案: 在@Alex 的帮助下

我在表中添加了 3 个新列,分别命名为年 (YYYY)、月(YYYY-MM) 和日(YYYY-MM-DD),并在表中添加了 3 个索引:

alter table vaadin_table add index (year, status);
alter table vaadin_table add index (month, status);
alter table vaadin_table add index (day, status);

现在我的查询是:

select year,status, count(1) from vaadin_table group by year, status;
select month,status, count(1) from vaadin_table group by month, status;
select day,status, count(1) from vaadin_table group by day, status;

我可以在 2 秒内得到结果!感谢您的所有帮助,非常感谢! Mysql 似乎不支持索引列上的函数,这使得我原来的帖子查询不起作用

编辑: 感谢所有回复。

为了让我的问题更清楚。我需要从表格中获取每日/每月/每年的统计数据。

因此,我使用以下按日/月/年数据的顺序分组:

substring(entry_date,1, 11) ---> YYYY-MM-DD

substring(entry_date,1, 7) ---> YYYY-MM

substring(entry_date,1, 4) ---> YYYY

所有这 3 列使我的查询变慢。

原问题: 我有一个 270 万行的表。它包含 3 列:名称、状态和 entry_date(YYYY-MM-DD HH:MM:SS)

CREATE TABLE IF NOT EXISTS test_table 
(id integer not null auto_increment primary key, 
name char(20) not null, status char(20) not null, 
entry_date datetime default 0);

我的目的是获取每个状态的每日数量:

SELECT substring(entry_date, 1, 11), status, count(1) 
FROM test_table 
GROUP BY
substring(entry_date, 1, 11), status;

它工作正常,但需要大约 10 秒才能返回结果。

为了优化它,我将索引添加到表中:

ALTER table test_table ADD INDEX test_index(entry_date, status);

我在网上阅读了一些类似的问题,都建议按顺序添加基于分组的索引。但这对我的情况没有帮助。是不是因为我使用了 entry_date 的子字符串?

请帮忙,谢谢

【问题讨论】:

  • 你的输入日期是日期时间值为什么你在它上面做子字符串这会降低性能的任何原因?
  • 为什么是substring(entry_date, 1, 11) 而不仅仅是entry_date
  • 你是对的;在条件或分组中的索引字段上使用任何函数会导致忽略索引(对于该条件或分组)。不幸的是,这甚至包括使用 CAST 或其他可用于获取日期时间字段日期的日期函数。
  • substring(entry_date, 1, 11) 正在获取忽略 HH:MM:SS 部分的 YYYY-MM-DD
  • 是的,在索引列上使用任何函数都会导致忽略索引。

标签: mysql sql indexing query-performance


【解决方案1】:
SELECT entry_date, status, count(1) 
FROM test_table 
GROUP BY
DATE(entry_date), status;

或者更好地添加带有DATE类型的额外列

ALTER TABLE test_table ADD COLUMN entry_date1 DATE;
UPDATE test_table  SET entry_date1=DATE(entry_date);

SELECT entry_date1, status, count(1) 
FROM test_table 
GROUP BY
entry_date1, status;

【讨论】:

  • 感谢您的回复。我更新了我的问题以使其更准确。
  • 您的更新没有任何改变。针对每条记录调用的任何函数都会破坏性能并且不会使用任何索引
  • 关于如何解决此类情况的任何建议?非常感谢
  • 这就是我回答你尝试的原因吗?
  • 我正要发布类似的答案。亚历克斯建议的实际上是正确的。制作三个不同的列(根据您的需要),对它们进行索引,然后将它们与 where 子句一起使用。 MySQL 不支持基于函数的索引。 (也许使用 Oracle ?)
【解决方案2】:

为了优化它,我的建议如下

更改查询

SELECT date(entry_date), status, count(1) 
FROM test_table 
GROUP BY
status,date(entry_date);

然后按以下列顺序创建索引

ALTER table test_table ADD INDEX test_index( status,entry_date);

【讨论】:

  • 那么在进行分组时会使用状态索引
猜你喜欢
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2022-10-13
  • 2022-11-19
  • 2021-12-06
  • 2016-12-01
  • 2020-07-05
相关资源
最近更新 更多