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

俊达3年前技术文章1025

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


相关文章

Solr常用API详细操作

Solr常用API详细操作

1. 监督集群的状态和统计返回监督器(overseer)的当前状态,各种监督器API的性能统计信息以及每种操作类型的最近10次故障/admin/collections?action=OVERSEERS...

数据湖技术之iceberg(八)Spark与Iceberg整合DDL操作

数据湖技术之iceberg(八)Spark与Iceberg整合DDL操作

1.CREATE TABLE 创建表Create table 创建Iceberg表,创建表不仅可以创建普通表还可以创建分区表,再向分区表中插入一批数据时,必须对数据中分区列进行排序,否则会出现文件关闭...

Yarn调度器和调度算法详解

Yarn调度器和调度算法详解

目前,Hadoop作业调度器主要有三种:FIFO、容量(Capacity Scheduler)和公平(Fair Scheduler)。Apache Hadoop3.1.3默认的资源调度器是C...

mysql binlog文件删除情况下恢复主从

mysql binlog文件删除情况下恢复主从

1、对主库的数据进行全库dump2、删除自建的从库数据库3、将主库数据source到从库(1)将全库dump文件传到从库服务器节点scp ./backup_2023-12-08_14_49_17.sq...

MySQL优化器特性(一)IN和Exists(semijoin)子查询优化策略

这篇文章中的SQL和执行计划在mysql 8.0.31环境下进行测试。测试的表结构和数据:表结构mysql> show create table tp\G...

linux下ext4类型文件系统/目录扩容

1、查看分区信息[root@172-16-121-112 ~]# fdisk -lDisk /dev/vda: 107.4 GB, 107374182400 bytes, 209715200 sect...

发表评论    

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