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

俊达2年前技术文章819

优化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进行拆分,使优化器可以选择最优的执行计划。


相关文章

MySQL 初始化推荐关注的参数

MySQL 初始化推荐关注的参数

前言新部署的 MySQL 实例如何配置?本 SOP 将提供一些 MySQL 关键参数及设置方法。必须设置的参数1. innodb_buffer_pool_size对于 innodb 表引擎来说,用户数...

PG的多版本并发控制(一)

PG的多版本并发控制(一)

一、 表系统字段几个比较重要概念1.1  tupletuple表示表中的数据行,在MySQL中用row表示。在表数据页中,主要分为普通的数据元祖和TOAST元祖。以下是一个普通数据元祖的结构,主要由三...

二进制日志(binlog)

二进制日志(binlog)

一、简介二进制日志(binlog)记录了数据库中所有的DDL和DML(除select语句)操作,语句以“事件”的形式保存,记录了数据库的更改变化,在主从复制和数据恢复中起着重要的作用。但要注意的一点是...

Doris 介绍及使用场景

Doris 介绍及使用场景

Doris 介绍                    Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据...

apache Kyuubi部署及对接hive

apache Kyuubi部署及对接hive

1、背景客户重度使用spark sql,但是使用spark thriftserver存在各种各样的问题,我们选择使用kyuubi来替代spark thriftserver的使用2、安装包下载下载地址:...

PromQL查询解析

一. 概述Prometheus除了存储数据外,还提供了一种强大的功能表达式语言 PromQL,允许用户实时选择和汇聚时间序列数据。表达式的结果可以在浏览器中显示为图形,也可以显示为表格数据,或者由外部...

发表评论    

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