MySQL Execution Plan--执行计划中的Type列
在一次的優(yōu)化過(guò)程中,由于沒(méi)有關(guān)注執(zhí)行計(jì)劃中type列,僅看key列來(lái)查看"使用到的索引",導(dǎo)致優(yōu)化過(guò)程走了不少?gòu)澛贰?/p>
以下面SQL為例:
SELECT wave_no, SUM(IF(picking_qty IS NULL, 0, picking_qty)) AS PICKED_QTY, SUM(IF(differ_qty IS NULL, 0, differ_qty)) AS PICKED_DIFFER_QTY, SUM(IF(relocate_qty IS NULL, 0, relocate_qty)) AS PICKED_RELOCATE_QTY FROM picking_locate_d WHERE yn = 0 AND wave_no IN ( 'BC76361213164811', 'BC76361213164810', ... 'BC76361213158692' ) AND org_No = '661' AND distribute_No = '763' AND warehouse_No = '612' GROUP BY wave_no;走索引查找的執(zhí)行計(jì)劃為:
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+ | 1 | SIMPLE | picking_locate_d | NULL | range | idx_wave_no | idx_wave_no | 153 | NULL | 14238 | 0.01 | Using index condition; Using where | +----+-------------+------------------+------------+-------+---------------+-------------+---------+------+-------+----------+------------------------------------+?走索引掃描執(zhí)行計(jì)劃為:
+----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+ | 1 | SIMPLE | picking_locate_d | NULL | index | idx_wave_no | idx_wave_no | 153 | NULL | 37660147 | 0.01 | Using where | +----+-------------+------------------+------------+-------+---------------+-------------+---------+------+----------+----------+-------------+?
上面兩個(gè)執(zhí)行計(jì)劃都使用索引idx_wave_no,但:
第一個(gè)執(zhí)行計(jì)劃影響行數(shù)為14238,與IN查詢中的值數(shù)量相同,其執(zhí)行計(jì)劃type列值為range,表示index range scan。
第二個(gè)執(zhí)行計(jì)劃影響行數(shù)為37660147,與整表數(shù)據(jù)量相同,其執(zhí)行計(jì)劃type列為index,表示index scan。
?
哪為啥索引查找是index range scan呢?通過(guò)MySQL trace工具查看,其中輸出包含以下信息:
"chosen_range_access_summary": { "range_access_plan": {"type": "range_scan","index": "idx_wave_no","rows": 5,"ranges": ["BC76361213164810 <= wave_no <= BC76361213164810","BC76361213164811 <= wave_no <= BC76361213164811","BC76361213158692 <= wave_no <= BC76361213158692"] /* ranges */ } /* range_access_plan */, "rows_for_plan": 5, "cost_for_plan": 9.01, "chosen": true } /* chosen_range_access_summary */其中查詢中WHERE子句:
wave_no IN ( 'BC76361213164811', 'BC76361213164810', 'BC76361213158692' )由于idx_wave_no為非唯一索引,雖然是等值查詢,仍需要從第一個(gè)等于指定值的索引記錄開(kāi)始掃描,直到第一個(gè)不等于指定值的索引記錄,因?yàn)楸环Q為范圍掃描(Range Scan) :
"ranges": ["BC76361213164810 <= wave_no <= BC76361213164810","BC76361213164811 <= wave_no <= BC76361213164811","BC76361213158692 <= wave_no <= BC76361213158692"]IN子句中的3個(gè)值被轉(zhuǎn)換為3次INDEX RANGE SCAN。
?
對(duì)于全索引掃描(INDEX SCAN),通過(guò)MySQL trace工具查看,其中輸出包含以下信息:
"considered_execution_plans": [{"plan_prefix": [] /* plan_prefix */,"table": "`picking_locate_d`","best_access_path": {"considered_access_paths": [{"rows_to_scan": 37660147,"access_type": "scan","resulting_rows": 3.77e7,"cost": 9.58e6,"chosen": true,"use_tmp_table": true}] /* considered_access_paths */} /* best_access_path */,"condition_filtering_pct": 100,"rows_for_plan": 3.77e7,"cost_for_plan": 9.58e6,"sort_cost": 3.77e7,"new_cost_for_plan": 4.72e7,"chosen": true} ] /* considered_execution_plans */其中access_type=scan表明操作為INDEX SCAN,rows_to_scan=37660147表名掃描整個(gè)索引上37660147行記錄。
?
通過(guò)DESC或EXPLAIN輸出的執(zhí)行計(jì)劃中,Type列的可選值分別對(duì)應(yīng):
all: 全表掃描 index: 索引全掃描 range: 索引范圍掃描,常用語(yǔ)<,<=,>=,between等操作 ref: 使用非唯一索引掃描或唯一索引前綴掃描,返回單條記錄,常出現(xiàn)在關(guān)聯(lián)查詢中 eq_ref: 類似ref,區(qū)別在于使用的是唯一索引,使用主鍵的關(guān)聯(lián)查詢 const/system: 單條記錄,系統(tǒng)會(huì)把匹配行中的其他列作為常數(shù)處理,如主鍵或唯一索引查詢 null: MySQL不訪問(wèn)任何表或索引,直接返回結(jié)果?
轉(zhuǎn)載于:https://www.cnblogs.com/gaogao67/p/10771113.html
總結(jié)
以上是生活随笔為你收集整理的MySQL Execution Plan--执行计划中的Type列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浅谈unity中gamma空间和线性空间
- 下一篇: ORA-08176 错误的一个案例