此查询需要 1.2 秒:
select * from alert limit 10000;
此查询耗时 33.99 秒:
select * from alert_version limit 10000;
alert_version 是一个 View ,它基本上是带有子查询的“警报”表:
select `alert`.`Alert_UID` AS `Alert_UID`,`alert`.`Rule_Name` AS `Rule_Name`,
`alert`.`Headline` AS `Headline`,`alert`.`Severity` AS `Severity`,
`alert`.`Device_UID` AS `Device_UID`,`alert`.`Configuration_Set_ID` AS `Configuration_Set_ID`,
`alert`.`Instance_UID` AS `Instance_UID`,`alert`.`Create_DateTime` AS `Create_DateTime`,
`alert`.`Delete_DateTime` AS `Delete_DateTime`,
( SELECT `version_build`.`Version`
from `version_build`
where ((`version_build`.`Instance_UID` = `alert`.`Instance_UID`)
and (`version_build`.`Create_DateTime` >= `alert`.`Create_DateTime`)
)
order by `version_build`.`Create_DateTime`
limit 1
) AS `version`
from `alert`
当我对此查询运行 EXPLAIN 时,我得到:
+----+--------------------+---------------+------+-----------------------------------------------------------------------------------+--------------------------+---------+----------------------------+--------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------------+------+-----------------------------------------------------------------------------------+--------------------------+---------+----------------------------+--------+------------------------------------------+
| 1 | PRIMARY | alert | ALL | NULL | NULL | NULL | NULL | 301274 | NULL |
| 2 | DEPENDENT SUBQUERY | version_build | ref | uid_version_build_create,version_build_Instance_UID,version_build_Create_DateTime | uid_version_build_create | 110 | insight.alert.Instance_UID | 6 | Using where; Using index; Using filesort |
+----+--------------------+---------------+------+-----------------------------------------------------------------------------------+--------------------------+---------+----------------------------+--------+------------------------------------------+
那么,您认为我应该怎么做才能获得可接受的性能?
更新:
每个请求,添加表格信息:
CREATE TABLE `alert` (
`Alert_UID` varchar(36) NOT NULL,
`Rule_Name` varchar(80) DEFAULT NULL,
`Headline` varchar(255) DEFAULT NULL,
`Severity` varchar(12) DEFAULT NULL,
`Device_UID` varchar(36) NOT NULL,
`Configuration_Set_ID` varchar(12) DEFAULT NULL,
`Instance_UID` varchar(36) NOT NULL,
`Create_DateTime` timestamp NOT NULL,
`Delete_DateTime` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`Alert_UID`),
KEY `alert_Create_DateTime` (`Alert_UID`,`Create_DateTime`),
KEY `alert_Headline` (`Headline`),
KEY `alert_Rule_Headline` (`Rule_Name`,`Headline`),
KEY `alert_Instance_UID` (`Instance_UID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
CREATE TABLE `version_build` (
`Instance_UID` varchar(36) NOT NULL,
`Version` varchar(12) NOT NULL,
`Build` varchar(30) DEFAULT NULL,
`Create_DateTime` timestamp NOT NULL,
UNIQUE KEY `uid_version_build_create`
(`Instance_UID`,`Version`,`Build`,`Create_DateTime`),
KEY `version_build_Instance_UID` (`Instance_UID`),
KEY `version_build_Create_DateTime` (`Create_DateTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
最佳答案
您将如何处理 10K 行?对于应用程序来说,这通常太多了,无法处理。
如果没有 ORDER BY
,您希望获得哪 10K 行?这是不可预测的。使用 ORDER BY
,查询可能会更慢。
子查询是性能 killer 。与速度共存。但是,您似乎正在以一种低效的方式进行“groupwise max”。该索引可能有帮助:
INDEX(Instance_UID, Create_DateTime, Version) -- in this order!
有关 groupwise-max 的更多信息:http://mysql.rjweb.org/doc.php/groupwise_max
关于mysql - 如何使对 MySQL View 的查询运行得更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50990603/