使用MYSQL上的数百万行优化汇总/分组查询

时间:2018-08-28 02:39:32

标签: mysql sql

我有一个包含近4.000.000行的MySQL表,其中包含超过100.000名员工的收入交易。

其中涉及三列:

  • 员工ID [VARCHAR和INDEX] (由于一位员工获得的收入不止一个,所以不是唯一的);
  • 收入类型 [还有VARCHAR和INDEX]
  • 收入价值 [十进制; 10,2]

我想做的事情对我来说似乎很简单。我想对每个雇员分组的所有收入发生总数进行汇总,并按一种类型进行过滤。 为此,我使用了以下代码:

SELECT 
    SUM(`value`) AS `SumofValue`,
    `type`,
    `EmployeeID`
FROM
    `Revenue`
GROUP BY `EmployeeID`
HAVING `type` = 'X'

结果应该是这样的:

  SUM        TYPE     EMPLOYEE ID
 R$ 250,00  X   250000008377
 R$ 5.000,00    X   250000004321
 R$ 3.200,00    X   250000005432
 R$ 1.600,00    X   250000008765
....

但是,这需要很长时间。我决定使用LIMIT命令将结果限制为仅1.000行,并且它可以正常工作,但是如果我要对整个表进行操作,则根据我的预测大约需要1小时。对于我来说似乎不太需要的东西,这似乎花了太多时间(但是我假设我可能是错的)。不仅如此,这还只是我打算将来进行的更为复杂的查询的第一步,在该查询中,除了员工ID之外,我还将按雇主ID分组(一个人可以从多个雇主)。

有什么方法可以优化这个?我的代码有什么问题吗?是否有任何秘密途径可以提高此操作的速度?我是否也应该为收入值的列编制索引?如果这是MySQL的限制,是否有任何选项可以更好地解决此问题? 我真的很感谢您。

预先感谢

披露:这是一个开放的政府数据库。所有这些数据均合法地向公众开放。

2 个答案:

答案 0 :(得分:1)

首先,使用WHERE而不是HAVING短语查询-在进行汇总之前过滤

SELECT SUM(`value`) AS `SumofValue`,
       MAX(type) as type,
       EmployeeID
FROM Revenue r
WHERE `type` = 'X'
GROUP BY EmployeeID;

接下来,尝试使用以下索引:(type, EmployeeId, value)。至少,这是查询的覆盖索引。 MySQL(取决于版本)可能足够聪明,也可以将其用于聚合。

答案 1 :(得分:0)

根据您定义的模式,为什么要使用VARCHAR数据类型作为Employee ID和Type。 您可以使用1-> X,2-> Y ...为Type创建引用表,因此基本上整数引用将用于事务表中的类型。
只需创建一个下面的虚拟表,然后执行耗时数小时的相同查询即可。即使您也会看到执行计划的重大变化。

CREATE TABLE test_transaction
(
Employee_ID BIGINT,
Type SMALLINT,
Income DECIMAL(10,2)
)

在Employee_ID和Type列上创建单独的索引。

相关问题