MySQL性能优化(七)优化or查询的另一个例子

俊达3年前技术文章1012

优化or查询的另外一个例子。

一个例子

SELECT msg.msg_id, msg.content , …
FROM msg 
    LEFT JOIN user ON msg.user_id = user.user_id  
    LEFT JOIN group ON msg.group_id = group.group_id
WHERE msg.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)  
     OR user.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)  
     OR group.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)


业务上只需要查询最近半分钟内有变化的数据。但是由于SQL语句的where条件中,用到了3个表的gmt_modified字段来过滤数据,必须要先将3个表的所有数据都关联出来,然后才能过滤数据,导致查询性能较差。


7-1.jpg


我们将SQL拆分成3个部分:

SQL片段一

SELECT msg.msg_id, msg.content , …
FROM msg 
    LEFT JOIN user ON msg.user_id = user.user_id  
    LEFT JOIN group ON msg.group_id = group.group_id
WHERE msg.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)


7-2.jpg

这种情况下,以MSG表作为驱动表,可以先过滤出msg表gmt_modified在半分钟之内的数据,然后再去关联user和group表,大大减少了需要关联的数据。

SQL片段二

SELECT msg.msg_id, msg.content , …
FROM msg 
    LEFT JOIN user ON msg.user_id = user.user_id  
    LEFT JOIN group ON msg.group_id = group.group_id
WHERE user.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)

7-3.jpg

类似的,这里可以以user表为驱动表,先过滤user表的数据,再进行关联。

SQL片段三

SELECT msg.msg_id, msg.content , …
FROM msg 
    LEFT JOIN user ON msg.user_id = user.user_id  
    LEFT JOIN group ON msg.group_id = group.group_id
WHERE group.gmt_modified >= date_sub('2018-04-29 09:31:44', INTERVAL 30 SECOND)


7-4.jpg

group表的数据极少变动,所以这个SQL片段基本很少需要执行。


将SQL拆分成3个部分后,优化器可以对这3个SQL片段分别优化,选取不同的表关联顺序。


总结

SQL的写法灵活,表达能力强,但是在一些特定的场景下,我们需要将复杂SQL进行拆分,使优化器可以选择最优的执行计划。


相关文章

PG初识

PG数据库是一种典型的C/S模型应用,不同的客户端通过TCP/IP进行连接、每个连接启动一个fork进程(多进程数据库)。一、pg逻辑架构1.1 pg与MySQL异同对比逻辑架构postgresMyS...

日志聚合工具loki

1、loki是什么Loki是一个水平可扩展,高可用性,多租户的日志聚合系统,受到Prometheus的启发。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签。...

Hadoop 重新编译-解决root用户提交任务报错Running as root is not allowed

Hadoop 重新编译-解决root用户提交任务报错Running as root is not allowed

本文主要解决Hadoop root用户无法提交问题Running as root is not allowedLinux架构:arm或者x86都可以Jdk版本:jdk1.8cmake版本:3.19Ha...

Kubernetes日志收集

Kubernetes日志收集

关于容器日志Docker的日志分为两类,一类是Docker引擎日志;另一类是容器日志。引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。本文主要介绍容器日志,容器日志可以理解是运行在容器内...

pgbench 压测工具

pgbench 压测工具

一、基本参数pgbench工具是Postgres自带的一款轻量型基准压测工具。它自定义相关场景下脚本进行1.1 初始化参数参数含义-i / --initialize调用初始化模式-I init_ste...

MySQL 8.0 新特性深度解析,成为数据库高手的必备!

MySQL 8.0 新特性深度解析,成为数据库高手的必备!

前言MySQL 5.7 在 2023 年 10 月 31 日起,就已经终止软件生命周期了,意味着 MySQL 官方将不再提供对 MySQL 5.7 版本的技术支持和更新。8.0 版本成为官方长期支持版...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。