所以我有一个错误日志需要分析。该日志是一个巨大的文件,约有 250 万行。
在该错误日志中,有一些字段称为:
EVENT_ATTRIBUTE 显示收集该事件的设备的名称 信息。
EVENT_SEVERITY 显示从 1 到 5 的数字。在此列中,我需要查找 1、2、4 和 5 的数量。
这是我使用的表格屏幕截图的链接:
我基本上需要获取 event_attribute 并计算 event_severity 的数量并将它们放在单独的列中。因此,与每个 event_attribute 相关的 1 和 2 的数量将被拆分,这样我就可以计算每个传感器(event_attribute)拾取的每种类型的错误量。
目前这是我的代码:
SELECT LEFT(EVENT_ATTRIBUTE, LOCATE('(', EVENT_ATTRIBUTE, 1)-1) AS
SensorName,
SUM(EVENT_SEVERITY = 1) CODE_1,
SUM(EVENT_SEVERITY = 2) CODE_2,
SUM(EVENT_SEVERITY = 4) ERROR_4,
SUM(EVENT_SEVERITY = 5) ERROR_5
FROM taddmapp.disc_event
WHERE EVENT_SEVERITY = 5 OR EVENT_SEVERITY = 4 OR EVENT_SEVERITY = 2 OR
EVENT_SEVERITY = 1
GROUP BY LEFT(EVENT_ATTRIBUTE, LOCATE('(', EVENT_ATTRIBUTE, 1)-1);
代码的LEFT(EVENT_ATTRIBUTE, LOCATE('(', EVENT_ATTRIBUTE, 1)-1)
部分只是删除正在使用的传感器的IP地址,另一个选择总和的数量状态代码。代码运行良好,为我带来了我需要的结果,但唯一的问题是它花费的时间太长。前几天我运行了它,执行这个查询花了一个多小时。我想知道是否有无论如何我都可以优化这个查询。我不太擅长 SQL,所以我需要帮助优化。
感谢您的宝贵时间!
最佳答案
如果无法向表中添加列,那么我们可以尝试重写查询以有效利用以 EVENT_ATTRIBUTE
作为前导列的索引。使用这样的索引:
... ON taddmapp.disc_event (EVENT_ATTRIBUTE,EVENT_SEVERITY)
我们尝试让 MySQL 使用该索引并避免“使用文件排序”操作来满足内部查询中的 GROUP BY。
SELECT SUBSTRING_INDEX(t.EVENT_ATTRIBUTE,'(',1) AS
SensorName
, SUM(t.CODE_1) AS CODE_1
, SUM(t.CODE_2) AS CODE_2
, SUM(t.ERROR_4) AS ERROR_4
, SUM(t.ERROR_5) AS ERROR_5
FROM ( SELECT e.EVENT_ATTRIBUTE
, SUM(e.EVENT_SEVERITY = 1) AS CODE_1
, SUM(e.EVENT_SEVERITY = 2) AS CODE_2
, SUM(e.EVENT_SEVERITY = 4) AS ERROR_4
, SUM(e.EVENT_SEVERITY = 5) AS ERROR_5
FROM taddmapp.disc_event e
WHERE e.EVENT_SEVERITY IN (1,2,4,5)
GROUP BY e.EVENT_ATTRIBUTE
) t
GROUP
BY SUBSTRING_INDEX(t.EVENT_ATTRIBUTE,'(',1)
注意:外部查询上的 GROUP BY 仍然需要“使用文件排序”操作,但这里的目标是让外部查询对更小的行集进行操作(假设内联 View 中的 GROUP BY将这 250 万行折叠成一个大小更合理的集合。)
如果我们只有一个裸柱,例如EVENT_ATTRIBUTE_PREFIX
仅填充了我们感兴趣的 EVENT_ATTRIBUTE
的前导部分,因此我们可以避免使用内联 View 。假设我们有该列,并且它是索引中的前导列,例如
... ON taddmapp.disc_event (EVENT_ATTRIBUTE_PREFIX,EVENT_SEVERITY)
然后 MySQL 可以利用该索引来满足 GROUP BY 操作,而不需要“使用文件排序”操作,查询如下:
SELECT e.EVENT_ATTRIBUTE_PREFIX AS SensorName
, SUM(e.EVENT_SEVERITY = 1) AS CODE_1
, SUM(e.EVENT_SEVERITY = 2) AS CODE_2
, SUM(e.EVENT_SEVERITY = 4) AS ERROR_4
, SUM(e.EVENT_SEVERITY = 5) AS ERROR_5
FROM taddmapp.disc_event e
WHERE e.EVENT_SEVERITY IN (1,2,4,5)
GROUP BY e.EVENT_ATTRIBUTE_PREFIX
关于mysql - 优化查看大量数据的 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44685273/