1、什么是派生表derived

关键字:子查询–>在From后where前的子查询

mysql> explain select *  from (select *  from t) a where id=2;
+----+-------------+------------+------+---------------+-------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+-------------+---------+-------+------+-------+
| 1 | PRIMARY | <derived2> | ref | <auto_key0> | <auto_key0> | 4 | const | 0 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 4 | NULL |
+----+-------------+------------+------+---------------+-------------+---------+-------+------+-------+

MySQL 5.7开始优化器引入derived_merge,可以理解为Oracle的子查询展开,有优化器参数optimizer_switch='derived_merge=ON’来控制,默认为打开。

但是仍然有很多限制,当派生子查询存在以下操作时该特性无法生效:UNION 、GROUP BY、DISTINCT、LIMIT/OFFSET以及聚合操作

2、派生表SQL优化一例

mysql> select @@version;
+------------+
| @@version |
+------------+
| 5.6.16-log |
+------------+ SELECT A.*, b.vendor_name, c.chinese_name, c.english_name, d.name AS category_name, e.value, a.season_code
FROM PR_XXX A
LEFT JOIN VXX B
ON A.VENDOR_ID = B.VENDOR_ID
LEFT JOIN BXX C
ON A.BRAND_ID = C.BRAND_ID
LEFT JOIN CXX D
ON A.CATEGORY_ID = D.CATEGORY_ID
LEFT JOIN PXX E
ON A.PRODUCT_ID = E.PRODUCT_ID
INNER JOIN (SELECT SS.PRODUCT_ID
FROM SKU_XXX SS
WHERE SS.ENABLED = 1
GROUP BY SS.PRODUCT_ID
HAVING SUM(SS.STORE) >= 1) ST
ON ST.PRODUCT_ID = A.PRODUCT_ID
WHERE A.vendor_id = 91011
AND A.enabled = 1
AND A.status = ''
AND a.season_code = ''
AND 1 = 1
AND a.brand_id = ''
AND E.KEY_NAME = 'XXX'
ORDER BY product_id LIMIT 0, 10

执行计划如下

++----+-------------+------------+-------------+----------------------------------------------------------------+-----------------------------------+---------+--------------------------+---------+---------------------------------------------------------------------------------+----+--
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------------+----------------------------------------------------------------+-----------------------------------+---------+--------------------------+---------+---------------------------------------------------------------------------------+
| 1 | PRIMARY | A | index_merge | PRIMARY,vendor_id,IDX_VENDOR_ID_STATUS,IDX_BRAND_ID,IDX_STATUS | IDX_VENDOR_ID_STATUS,IDX_BRAND_ID | 9,8 | NULL | 5 | Using intersect(IDX_VENDOR_ID_STATUS,IDX_BRAND_ID); Using where; Using filesort |
| 1 | PRIMARY | B | const | PRIMARY | PRIMARY | 8 | const | 1 | NULL |
| 1 | PRIMARY | C | const | PRIMARY | PRIMARY | 8 | const | 1 | Using where |
| 1 | PRIMARY | D | eq_ref | PRIMARY | PRIMARY | 8 | ger-prd-db.A.category_id | 1 | NULL |
| 1 | PRIMARY | E | ref | IDX_PRODUCT_PROPERTY_PRODUCT_ID | IDX_PRODUCT_PROPERTY_PRODUCT_ID | 8 | ger-prd-db.A.product_id | 3 | Using where |
| 1 | PRIMARY | <derived2> | ref | <auto_key0> | <auto_key0> | 9 | ger-prd-db.A.product_id | 10 | Using index |
| 2 | DERIVED | SS | index | IDX_PRODUCT_ID | IDX_PRODUCT_ID | 9 | NULL | 1715829 | Using where |
+----+-------------+------------+-------------+----------------------------------------------------------------+-----------------------------------+---------+--------------------------+---------+---------------------------------------------------------------------------------+

关键表索引信息

mysql> show index  from PR_XXX ;
+---------+------------+-------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| PR_XXX | 0 | PRIMARY | 1 | product_id | A | 283783 | NULL | NULL | | BTREE | | |
| PR_XXX | 0 | vendor_id | 1 | vendor_id | A | 92 | NULL | NULL | | BTREE | | |
| PR_XXX | 0 | vendor_id | 2 | product_code | A | 283783 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_VENDOR_ID_STATUS | 1 | vendor_id | A | 82 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_VENDOR_ID_STATUS | 2 | status | A | 392 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_BRAND_ID | 1 | brand_id | A | 2866 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_STATUS | 1 | status | A | 10 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_PRODUCT_CATEGORY_ID | 1 | category_id | A | 276 | NULL | NULL | | BTREE | | |
| PR_XXX | 1 | IDX_SPU_ID | 1 | spu_id | A | 283783 | NULL | NULL | YES | BTREE | | |
+---------+------------+-------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
9 rows in set (0.00 sec)
mysql> show index from SKU_XXX;
+-----------+------------+----------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| SKU_XXX | 0 | PRIMARY | 1 | sku_store_id | A | 1715829 | NULL | NULL | | BTREE | | |
| SKU_XXX | 1 | IDX_SKU_ID | 1 | sku_id | A | 1715829 | NULL | NULL | YES | BTREE | | |
| SKU_XXX | 1 | IDX_PRODUCT_ID | 1 | product_id | A | 857914 | NULL | NULL | YES | BTREE | | |
+-----------+------------+----------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

建议进行SQL改写

SELECT A.*, b.vendor_name, c.chinese_name, c.english_name, d.name as category_name, e.value, a.season_code
FROM PR_XXX A
LEFT JOIN VXX B
ON A.VENDOR_ID = B.VENDOR_ID
LEFT JOIN BXX C
ON A.BRAND_ID = C.BRAND_ID
LEFT JOIN CXX D
ON A.CATEGORY_ID = D.CATEGORY_ID
LEFT JOIN PXX E
ON A.PRODUCT_ID = E.PRODUCT_ID
INNER JOIN SKU_XXX SS
ON SS.ENABLED = 1
and SS.PRODUCT_ID = A.PRODUCT_ID
where A.vendor_id = 20
AND A.enabled = 1
AND A.status = ''
AND a.season_code = '18SS'
AND 1 = 1
AND a.brand_id = ''
AND E.KEY_NAME = 'BrandID'
and SS.ENABLED = 1
GROUP BY a.PRODUCT_ID
having SUM(SS.STORE) >= 1
ORDER BY a.product_id limit 0, 10;

改写后的执行计划

+----+-------------+-------+-------------+----------------------------------------+-----------------------------------+---------+--------------------------+------+--------------------------------------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------------+----------------------------------------+-----------------------------------+---------+--------------------------+------+--------------------------------------------------------------------------------------------------+
| 1 | SIMPLE | A | index_merge | PRIMARY,vendor_id,....................,| IDX_VENDOR_ID_STATUS,IDX_BRAND_ID | 9,8 | NULL | 5 | Using intersect(IDX_VENDOR_ID_STATUS,IDX_BRAND_ID); Using where; Using temporary; Using filesort |
| 1 | SIMPLE | B | const | PRIMARY | PRIMARY | 8 | const | 1 | NULL |
| 1 | SIMPLE | C | const | PRIMARY | PRIMARY | 8 | const | 1 | Using where |
| 1 | SIMPLE | D | eq_ref | PRIMARY | PRIMARY | 8 | ger-prd-db.A.category_id | 1 | NULL |
| 1 | SIMPLE | SS | ref | IDX_PRODUCT_ID | IDX_PRODUCT_ID | 9 | ger-prd-db.A.product_id | 2 | Using where |
| 1 | SIMPLE | E | ref | IDX_PRODUCT_PROPERTY_PRODUCT_ID | IDX_PRODUCT_PROPERTY_PRODUCT_ID | 8 | ger-prd-db.A.product_id | 3 | Using where |
+----+-------------+-------+-------------+----------------------------------------+-----------------------------------+---------+--------------------------+------+--------------------------------------------------------------------------------------------------+

优化前:2 rows in set (2.12 sec)
优化后:2 rows in set (0.00 sec)

MySQL派生表(derived)优化一例的更多相关文章

  1. MySQL 派生表(Derived Table) Merge Optimization

    本文将通过演示告诉你:MySQL中派生表(Derived Table)是什么?以及MySQL对它的优化. Background 有如下一张表: mysql> desc city; +------ ...

  2. 数据库~Mysql派生表注意的几点~关于百万数据的慢查询问题

    基础概念 派生表是从SELECT语句返回的虚拟表.派生表类似于临时表,但是在SELECT语句中使用派生表比临时表简单得多,因为它不需要创建临时表的步骤. 术语:*派生表*和子查询通常可互换使用.当SE ...

  3. MySQL的表的优化和列类型的选择

    列选择原则: 1:字段类型优先级 整型 > date,time  >  enum,char>varchar > blob 列的特点分析: 整型: 定长,没有国家/地区之分,没有 ...

  4. mysql服务器iowait高优化一例完整深入解析

    我们有一服务器,上面运行着两个mysql实例,这几天iowait一直很高,在20-30%,下午特地专门排查和解决了下,相关过程整理如下. 该服务器有两个挂载盘,服务器在阿里云上,一个系统盘,一个数据盘 ...

  5. mysql大表如何优化

    作者:哈哈链接:http://www.zhihu.com/question/19719997/answer/81930332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处 ...

  6. Mysql学习总结(17)——MySQL数据库表设计优化

    1.选择优化的数据类型 MySQL支持很多种不同的数据类型,并且选择正确的数据类型对于获得高性能至关重要.不管选择何种类型,下面的简单原则都会有助于做出更好的选择: (1).更小通常更好 一般来说,要 ...

  7. mysql 两表索引优化

    建表语句 CREATE TABLE IF NOT EXISTS `class`( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `card` INT(1 ...

  8. mysql 单表索引优化

    建表语句 CREATE TABLE IF NOT EXISTS `article` ( `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMEN ...

  9. mysql 修复表和优化表

    REPAIR TABLE `table_name` 修复表 OPTIMIZE TABLE `table_name` 优化表

随机推荐

  1. linux下rename命令使用(可以实现文件批量重名)

    rename命令使用 把所有文件中的@符号去掉 wang@2a.pngzhang@2a.pngzhou@2a.pnghaha@2a.pngmama@2a.png CentOS:rename \@2a. ...

  2. linux tcpdump抓取HTTP包的详细解释

    tcpdump tcpdump是linux系统自带的抓包工具,主要通过命令行的方式,比较适合在线上服务器进行抓包操作,如果是windows或者ubuntu完全可 以选择一些图形化的工具,ubuntu比 ...

  3. Unity Time.timeScale

    原创网址: http://www.xuanyusong.com/archives/2956 项目里面一直在用Time.timeScale来做游戏的 1倍 2倍整体加速,今天我仔细看了一下Time.ti ...

  4. CONCAT substr group_concat find_in_set

    (SELECT p.*,(SELECT CONCAT(m.name,m.id) FROM service_fastfix_category m WHERE m.id=SUBSTR(p.id,1,4)) ...

  5. Storm概念学习系列之Task任务

    不多说,直接上干货! 每一个Spout/Bolt的线程称为一个Task. Task任务 Task是运行Spout或Bolt的单元,每一个Spout/Bolt的线程称为一个Task. 在Storm 0. ...

  6. Storm概念学习系列之storm核心组件

    不多说,直接上干货! Storm核心组件 了解 Storm 的核心组件对于理解 Storm 原理非常重要,下面介绍 Storm 的整体,然后介绍 Storm 的核心. Storm 集群由一个主节点和多 ...

  7. 【JavaEE】Web Service 的工作原理

    Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...

  8. 从左到右的滑块-Au3

    说明:使用selenium自动化登陆时会弹出滑块,做人机识别,使用Au3模拟鼠标移动轨迹--可验证通过 #include <MsgBoxConstants.au3> #include &l ...

  9. P1868 饥饿的奶牛

    题目描述 有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字. 现用汉语翻译为: 有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草.你可以选择任意区间但不能有 ...

  10. 显示单位px、dip以及sp的区别

    dip: Device Independent Pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA推荐使用这个,不依赖像素. p ...