我在整个项目中处理缓慢的查询。我编制了大量的索引,但结果却毫无结果。我有很多来自SCADA系统的日志(每分钟数千条),我试图为每个SCADA系统计算它们,并将它们显示在简单的表中。但问题是,当独立运行时,我在主查询中拥有的每个子查询都相当快,但在一个片段中,查询大约需要50秒或更多时间。
我做了这个修复-我在InnoDB表(logs_mgmt)上进行了全文搜索,以搜索SCADA系统的所有消息,为每个SCADA查找一个错误。它杀死了MySQL,所以我做了一个触发器,当数据存储到主表logs_mgmt时触发它。此触发器将错误消息存储到新表logs_last_three_days_mgmt。有一个事件每天早上都会发生,并清除所有3天以上的排行。
有什么办法来改进这个选择吗?如何更改此查询以提高其性能?
我的问题是:
SELECT scada_systems_mgmt.scada_system_id,
scada_systems_mgmt.scada_name,
scada_systems_mgmt.scada_description,
scada_systems_mgmt.scada_url,
(
SELECT COUNT(*)
FROM error_logs_mgmt
WHERE error_logs_mgmt.scada_id = scada_systems_mgmt.scada_system_id
AND error_logs_mgmt.real_dt > DATE_SUB(NOW(), INTERVAL 3 DAY)
AND error_logs_mgmt.id >
IF(
(
SELECT @ret_id = error_logs_mgmt.id
FROM error_logs_mgmt
WHERE error_logs_mgmt.scada_id = scada_systems_mgmt.scada_system_id
AND solved=1
ORDER BY id DESC
LIMIT 1
) IS NOT NULL,
@ret_id,
(
SELECT MIN(id)
FROM error_logs_mgmt
WHERE error_logs_mgmt.scada_id = scada_systems_mgmt.scada_system_id
)
)
) AS scada_errors_count,
(
SELECT COUNT(alarms_mgmt.id)
FROM alarms_mgmt
WHERE alarms_mgmt.scada_id = scada_systems_mgmt.scada_system_id
AND alarms_mgmt.solved = 0
) as scada_alarms,
users_scada_login_mgmt.scada_login,
users_scada_login_mgmt.scada_password
FROM scada_systems_mgmt
LEFT JOIN (
SELECT users_scada_login_mgmt.scada_login,
users_scada_login_mgmt.scada_password,
users_scada_login_mgmt.scada_system_id
FROM users_scada_login_mgmt
WHERE users_scada_login_mgmt.user_id = " . (int)$user_id . "
) users_scada_login_mgmt
ON users_scada_login_mgmt.scada_system_id = scada_systems_mgmt.scada_system_id
ORDER BY users_scada_login_mgmt.scada_login DESClogs_last_three_days与logs_mgmt相同:
CREATE TABLE `logs_last_three_days_mgmt` (
`id` bigint(20) NOT NULL,
`scada_id` int(11) NOT NULL,
`dt` datetime NOT NULL,
`real_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`message` text NOT NULL,
`solved` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `scada_id` (`scada_id`),
KEY `solved` (`solved`),
KEY `real_dt` (`real_dt`),
CONSTRAINT `logs_last_three_days_mgmt_ibfk_1` FOREIGN KEY (`scada_id`) REFERENCES `scada_systems_mgmt` (`scada_system_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8在其他表中,只有几十行,所以我认为它们不是性能杀手。
发布于 2015-08-27 07:03:26
我会中断这些查询,并将结果存储在临时表中。我会用一个存储的程序。在许多表中有这样的子查询会产生约束,并可能产生一些锁定。此外,使用查询中的列上>将使Mysql对该列进行扫描(即使它是索引的)。>=或< <= (中间使用)。
https://dba.stackexchange.com/questions/112319
复制相似问题