iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >一个left join SQL 简单优化分析
  • 777
分享到

一个left join SQL 简单优化分析

2024-04-02 19:04:59 777人浏览 安东尼
摘要

有个关联查询的sql,需要2秒多,于是进行查看一番: SELECT a.id, a.brand_id, a.series_id, a.product_id, a.material_i

有个关联查询的sql,需要2秒多,于是进行查看一番:


SELECT
	a.id,
	a.brand_id,
	a.series_id,
	a.product_id,
	a.material_id,
	a.custom_cateGory_id,
	a.price,
	a.product_url,
	a.organ_id,
	.....
FROM
	pm_brand_xxxx a
LEFT JOIN pm_brand_yyyyy d ON a.series_id = d.id
WHERE
	a.is_delete = 0
AND d.is_delete = 0
AND a.organ_id = 'Cxxx'
AND a.brand_id = 6491603
AND d.brand_id = 6491603
AND a.model_flag = 14;

Mysql> show profile for query 4;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000072 |
| checking permissions | 0.000002 |
| checking permissions | 0.000002 |
| Opening tables       | 0.000011 |
| init                 | 0.000026 |
| System lock          | 0.000007 |
| optimizing           | 0.000016 |
| statistics           | 0.000142 |
| preparing            | 0.000018 |
| executing            | 0.000002 |
| Sending data         | 2.281192 |<<<<<<<执行的主要时间消耗
| end                  | 0.000007 |
| query end            | 0.000011 |
| closing tables       | 0.000011 |
| freeing items        | 0.000030 |
| logging slow query   | 0.000003 |
| logging slow query   | 0.000102 |
| cleaning up          | 0.000022 |
+----------------------+----------+

+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys                                                                                                 | key                                                                       | key_len | ref   | rows  | filtered | Extra                                                                                                                                          |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | SIMPLE      | d     | NULL       | ref         | PRIMARY,idx_pm_yyyy_bid                                                                                        | idx_pm_yyyyy_bid                                                        | 9       | const |     1 |    10.00 | Using where                                                                                                                                    |
|  1 | SIMPLE      | a     | NULL       | index_merge | idx_pm_xxxx_sid,idx_pm_xxx_bid,idx_pm_brand_xxxx_organ                                                         | idx_pm_xxx_organ,idx_pm_brand_xxxx_bid                                   | 99,9    | NULL  | 11314 |     0.04 | Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where; Using join buffer (Block Nested Loop)                                        |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------+-------+----------+------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)


从执行计划来看,d表是做了驱动表,a做了被驱动表

d表 type = ref ,使用非唯一性索引或者唯一索引的前缀扫描,返回匹配某个单独值的记录行,这里使用了索引idx_pm_yyyyy_bid,该索引正是brand_id上的索引,

即是说,在和a表的关联中d先通过brand_id来查找记录行,再通过相应记录的id去和a表的series_id做匹配。

我查看相应的记录数,发现a表145万的大表,d表是4075的小表。


a表

mysql> select count(*) from pm_xxxxxx;

+----------+

| count(*) |

+----------+

|  1459777 |

+----------+

1 row in set (0.27 sec)


d表:


mysql> select count(*) from pm_yyyyyy;

+----------+

| count(*) |

+----------+

|     4075 |

+----------+

1 row in set (0.00 sec)



而 a表是type=index_merge 索引合并,这里走了idx_pm_xxx_organ(organ_id),idx_pm_brand_xxxx_bid(brand_id) ,extra 是

Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where; Using join buffer (Block Nested Loop) 

Using intersect正说明了这里使用了(idx_pm_xxxxx_organ,idx_pm_xxxx_bid)的交集

Using where 是用model_flag等这些其他条件的过滤

Using join buffer (Block Nested Loop) 说明使用BNL的算法进行匹配

 BNL 算法是将外层循环的行/结果集(驱动表)存入join buffer, 内层循环的每一行与整个buffer中的记录做比较,从而减少内层循环的次数.


举例来说,外层循环的结果集是100行,使用NLJ 算法需要扫描内部表100次,如果使用BNL算法,先把对Outer Loop表(外部表)每次读取的10行记录放到join buffer,然后在InnerLoop表(内部表)中直接匹配这10行数据,内存循环就可以一次与这10行进行比较, 这样只需要比较10次,对内部表的扫描减少了9/10。所以BNL算法就能够显著减少内层循环表扫描的次数.


在这里就是d表中取得结果集分批放入buffer中与a表进行匹配。


而这个语句无论如何都要2秒中,也在我们的认识中小表驱动大表并没错,我的猜想应该就是在进行BNL时消耗了时间,表现到过程中就是 Sending data 的时间消耗增多。

吐槽的是mysql中貌似没有什么办法来多方面看查询消耗了。

我想到的是如果该表现有sql关联的顺序是否性能能改善,在该sql中,我发现了两个条件:

AND a.brand_id = 6491603

AND d.brand_id = 6491603

在业务逻辑上这两个表的字段应该是一致的,如果我将d表的d.brand_id = 6491603去掉,以上的执行计划应该会改变,于是去掉之后执行,执行时间非常小。


mysql> show profile for query 1;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000080 |
| checking permissions | 0.000002 |
| checking permissions | 0.000002 |
| Opening tables       | 0.000012 |
| init                 | 0.000030 |
| System lock          | 0.000006 |
| optimizing           | 0.000014 |
| statistics           | 0.000130 |
| preparing            | 0.000016 |
| executing            | 0.000001 |
| Sending data         | 0.027325 |
| end                  | 0.000003 |
| query end            | 0.000015 |
| closing tables       | 0.000005 |
| freeing items        | 0.000014 |
| cleaning up          | 0.000009 |
+----------------------+----------+
16 rows in set, 1 warning (0.00 sec)

看其执行计划:
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------------------------+-------+----------+---------------------------------------------------------------------------------------------------------+
| id | select_type | table | partitions | type        | possible_keys                                                                                                 | key                                                                       | key_len | ref                     | rows  | filtered | Extra                                                                                                   |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------------------------+-------+----------+---------------------------------------------------------------------------------------------------------+
|  1 | SIMPLE      | a     | NULL       | index_merge | idx_pm_xxxxx_sid,idx_pm_xxxxx_bid,idx_pm_xxxx_organ                                                           | idx_pm_xxxxx_organ,idx_pm_xxxx_bid                                        | 99,9    | NULL                    | 11315 |     1.00 | Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where                                        |
|  1 | SIMPLE      | d     | NULL       | eq_ref      | PRIMARY                                                                                                       | PRIMARY                                                                   | 8       | xxxx.a.series_id |     1 |    10.00 | Using where                                                                                             |
+----+-------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------+---------+-------------------------+-------+----------+---------------------------------------------------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)




发现变成了a表做驱动表,d表做被驱动表,从extra列看

a表是Using intersect(idx_pm_xxxxx_organ,idx_pm_xxxx_bid); Using where   依然是使用索引合并,where条件来取结果,使用了idx_pm_xxxxx_organ,idx_pm_xxxx_bid 连个索引。

d表走PRIMARY 主键索引,从ref列来看是通过a表的series_id 来关联,这样效率表提升了。


需要说的一点是,小结果集并不代表就是小表,大表也可以有小结果集,当大表用来被匹配并被扫描多次,自然效率并不高.



您可能感兴趣的文档:

--结束END--

本文标题: 一个left join SQL 简单优化分析

本文链接: https://www.lsjlt.com/news/46997.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQL语句优化之JOIN和LEFT JOIN 和 RIGHT JOIN语句的示例分析
    小编给大家分享一下SQL语句优化之JOIN和LEFT JOIN 和 RIGHT JOIN语句的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!在数据库的应用中,我们经常需要对数据库进...
    99+
    2024-04-02
  • sql中left join的示例分析
    这篇文章主要为大家展示了“sql中left join的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“sql中left join的示例分析”这篇文章吧。网...
    99+
    2024-04-02
  • mysql 优化慢复杂sql (多个left join 数量过大 order by 巨慢)
    前沿 懒得看过程的话这里直接总结一下最后的解决方法: 如果不能直接减少主表的数据(小表驱动大表),就想办法把多个left join合成一个子查询,速度是否变快,没有的话再在子查询底下加一个havin&...
    99+
    2023-09-13
    mysql sql 数据库
  • 查一次left join没有走索引以及原因分析
    目录查一次left join没有走索引的原因因此解决方案总结查一次left join没有走索引的原因 线上有个查询sql,原来是inner join 查询没有问题,后来应业务要求改成left join之后, 查询时间就暴...
    99+
    2023-03-23
    left join left join索引 left join没有走索引
  • 数据库中如何使用LEFT JOIN优化多个子查询
    小编给大家分享一下数据库中如何使用LEFT JOIN优化多个子查询,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.SQL1OL...
    99+
    2024-04-02
  • 查一次left join没有走索引以及原因分析
    目录查一次left join没有走索引的原因因此解决方案总结查一次left join没有走索引的原因 线上有个查询sql,原来是inner join 查询没有问题,后来应业务要求改成...
    99+
    2023-03-23
    left join left join索引 left join没有走索引
  • 分享几个简单MySQL优化小妙招
    SQL语句执行顺序 设置大小写不敏感 查看大小写是否敏感:show variables like '%lower_case_table_names%'; windo...
    99+
    2024-04-02
  • 优化SQL SELECT语句性能的6个简单技巧分别是什么
    本篇文章给大家分享的是有关优化SQL SELECT语句性能的6个简单技巧分别是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。SELECT语...
    99+
    2024-04-02
  • 二十三、SQL 数据分析实战(10个简单的SQL题目)
    文章目录 题目1: 比赛名单整理题目2: 热门游戏排行题目3: 社区生鲜App覆盖分析题目4: 社区团购行为分析题目5: 统计字符出现次数题目6: 找出各类别商品销量最高的商品题目7: 找出每...
    99+
    2023-08-31
    sql 数据分析 数据库 mysql 原力计划
  • 一个关于遗传算法优化的简单例子
    在课程上学了一些关于遗传算法的思想的,想用这个思想来写一个简单的小例子。 先来说遗传算法的思想:遗传算法是模拟生物的遗传、变异、选择、进化来对问题的解进行优化,可以理解为将一组初始解看成是“基因”,在求解的开始设置一个过滤器,对“基因”进...
    99+
    2023-01-31
    算法 例子 简单
  • 优化SQL系统变量分析
    这篇文章主要介绍“优化SQL系统变量分析”,在日常操作中,相信很多人在优化SQL系统变量分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”优化S...
    99+
    2024-04-02
  • 优化MySQL的3个简单小调整分别是什么
    本篇文章为大家展示了优化MySQL的3个简单小调整分别是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。如果你不改变 MySQL 的缺省配置,你的服务器的性能就像...
    99+
    2024-04-02
  • 简单的创建数据库sql语句分析
    今天小编给大家分享的是简单的创建数据库sql语句分析,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。创建数据库的sql语句是“CREATE DATAB...
    99+
    2024-04-02
  • oracle优化sql的内部过程分析
    本篇内容主要讲解“oracle优化sql的内部过程分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“oracle优化sql的内部过程分析”吧!Oracle对sq...
    99+
    2024-04-02
  • 对SQL语句进行分析和优化
    安装和查看ORACLE执行计划ORACLE在执行SQL语句时使用的步骤的集合叫做执行计划前起条件:    在目录:$ORACLE_HOME/RDBMS/ADMIN目录下的执行u...
    99+
    2024-04-02
  • SQL查询优化原理实例分析
    今天小编给大家分享一下SQL查询优化原理实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。有一张财务流水表,未分库分表,...
    99+
    2023-07-02
  • 分析SQL优化的limit分页延迟关联
    这篇文章主要介绍“分析SQL优化的limit分页延迟关联”,在日常操作中,相信很多人在分析SQL优化的limit分页延迟关联问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析...
    99+
    2024-04-02
  • Oracle q' 简化单引号转义分析
    这篇文章主要讲解了“Oracle q' 简化单引号转义分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Oracle q' 简化单引号转义分...
    99+
    2024-04-02
  • MySQL数据库性能优化之SQL优化的示例分析
    这篇文章将为大家详细讲解有关MySQL数据库性能优化之SQL优化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  注:这篇文章是以 MySQL 为背景,很多内容...
    99+
    2024-04-02
  • 分享一个简单的java爬虫框架
    反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架可以自定义的部分有:请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式储存方式(默认储存在f盘的html文件夹下),...
    99+
    2023-05-30
    java 爬虫框架 ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作