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

俊达1年前技术文章359

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


相关文章

CDH-集群节点下线

CDH-集群节点下线

1、前期准备确认下线节点确认节点组件信息确认下线节点数据存储大小确定剩余节点存储大小如果下线节点数据存储大小大于剩余节点存储大小,则不能进行下线,可能存在数据丢失的情况2、操作首先确认待下线节点中是否...

MySQL优化器特性(八)索引范围扫描成本计算

MySQL优化器特性(八)索引范围扫描成本计算

range执行计划中的range表示索引范围扫描。索引范围扫描的执行过程大致如下:1、根据where条件中索引字段的条件,定位到索引结构中的第一条满足条件的记录。2、根据索引中记录的rowid,到表中...

HDFS元数据损坏恢复方法

HDFS元数据损坏恢复方法

HDFS JournalNode 编辑目录(dfs.journalnode.edits.dir)下数据损坏(单节点损坏或所有节点数据损坏),如何恢复 HDFS?单节点损坏a)  &...

keycloak高可用部署

keycloak高可用部署

添加keycloak应用rancher应用商店模式添加keycloak仓库地址rancher应用商店添加bitnami的helm仓库地址https://charts.bitnami.com/bitna...

shell脚本-expect

shell脚本-expect

一、概述       Expect是建立在tcl基础上的一个工具,Expect 是用来进行自动化控制和测试的工具。主要解决shell脚本中不可交互的问题。       在一些需要交互输入指令的场景下,...

发表评论    

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