mysql - 如何使对 MySQL View 的查询运行得更快?

标签 mysql performance view query-optimization

此查询需要 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/

相关文章:

php - Linux连接mysql PHP

CSS 叠加 SmartGWT 样式

Android - OpenGL FloatBuffer 与 IntBuffer

具有形状和发光的android自定义 View

mysql - 从列中选择最大值及其相应的日期

mysql - 网络和数据库关系基础设施

mysql - 使用另一个表中的列更新一个表中的时间戳列

performance - HDFS序列文件性能调优

c++ - 为什么图像出现在我的 QGraphicsView 派生类中的错误位置?

html - jEditable TextArea,我需要在保存时保持格式,但在编辑时显示用户友好的文本(MVC3)