zoukankan      html  css  js  c++  java
  • mysql(二) 慢查询分析(一)

    如下表结构:

    CREATE TABLE `trade_order` (
      `order_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单编号',
      `total_price` bigint(20) DEFAULT NULL COMMENT '订单总价',
      `item_name` varchar(128) DEFAULT NULL COMMENT '商品名称',
      `mobile` varchar(16) DEFAULT NULL COMMENT '下单电话',
      `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `gmt_modify` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`order_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=239 DEFAULT CHARSET=utf8mb4;
    CREATE TABLE `trade_sub_order` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `order_id` bigint(20) DEFAULT NULL COMMENT '订单号',
      `item_price` bigint(20) DEFAULT NULL COMMENT '商品单价',
      `item_nums` int(11) DEFAULT NULL COMMENT '商品数量',
      `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `gmt_modify` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      KEY `order_index` (`order_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1227 DEFAULT CHARSET=utf8mb4;

    在执行联合查询时,如下2种写法的执行计划有明显差别。

    第一种:

    select * from trade_order left join `trade_sub_order` using(`order_id`) order by `trade_order`.`order_id` desc;

    第二种:

    select * from trade_order left join `trade_sub_order` using(`order_id`) order by `trade_sub_order`.`order_id` desc;

    两者的差别在于order by的表字段不同。

    看执行计划:

    第一种的执行计划:

    第二种的执行计划:

    rows的差别忽略,因为数据在不停的新增过程中。

    第一种方式有主键索引,不需要使用临时表。第二种全表扫描,使用临时表,使用文件排序。

    这里面的关键问题在于,MySQL 表关联的算法是“Nest Loop Join”,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后再合并结果(临时表)。

    在explain中,第一行出现的表就是驱动表,对于驱动表字段的排序可以直接进行,对于非驱动表字段的排序需要对循环查询的合并结果(临时表)进行排序。所以在第二种写法下就会出现Using temporary。而且由于对非驱动表字段排序,导致将驱动表的全表数据作为驱动表的结果集,产生全表扫描,无法使用到主键索引。

    所以,在explain中,有Using temporary时,需要关注是否使用非驱动表字段做排序处理。

    驱动表的定义:

    在进行多表连接查询时,

    • 指定了连接条件,满足查询查询条件的记录数少的表为驱动表;
    • 未指定连接条件,行数少的表为驱动表;
  • 相关阅读:
    [py]str list切片-去除字符串首尾空格-递归思想
    [py]python面向对象的str getattr特殊方法
    [py]python多态-动态语言的鸭子类型
    [py]py2自带Queue模块实现了3类队列
    【Unity技巧】制作一个简单的NPC
    java7 新特性 总结版
    【游戏周边】Unity,UDK,Unreal Engine4或者CryENGINE——我应该选择哪一个游戏引擎
    【Unity Shaders】Transparency —— 使用alpha通道创建透明效果
    记录最近的几个bug
    理解WebKit和Chromium: 调试Android系统上的Chromium
  • 原文地址:https://www.cnblogs.com/asfeixue/p/9125172.html
Copyright © 2011-2022 走看看