關鍵字:子查詢–>在From後where前的子查詢mysql
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’來控制,默認爲打開。sql
可是仍然有不少限制,當派生子查詢存在如下操做時該特性沒法生效:UNION 、GROUP BY、DISTINCT、LIMIT/OFFSET以及聚合操做優化
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 = '1' AND a.season_code = '5678' AND 1 = 1 AND a.brand_id = '1234' AND E.KEY_NAME = 'XXX' ORDER BY product_id LIMIT 0, 10
執行計劃以下spa
++----+-------------+------------+-------------+----------------------------------------------------------------+-----------------------------------+---------+--------------------------+---------+---------------------------------------------------------------------------------+----+-- | 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 | +----+-------------+------------+-------------+----------------------------------------------------------------+-----------------------------------+---------+--------------------------+---------+---------------------------------------------------------------------------------+
關鍵表索引信息code
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改寫blog
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 = '1' AND a.season_code = '18SS' AND 1 = 1 AND a.brand_id = '247' 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)it