一个奇怪的执行计划,关联查询中一个表未跟其他任何表关联
Posted 渔夫数据库笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个奇怪的执行计划,关联查询中一个表未跟其他任何表关联相关的知识,希望对你有一定的参考价值。
1.数据库版本:
8.0.13
2.问题发现
监控发现一个并发查询导致数据库cpu使用率过高,我找到该sql看看有没有优化的余地,但是看了执行计划后,发现这个执行计划就很奇怪,下面发给大家看一下。
我们发现执行计划显示先访问了g表,然后紧接着访问了a表,问题是g 表和a 在sql中并没有关联字段,那么g表怎么和a表关联呢?其实这里g表没有跟其他表关联。g表通过主键(shop_no)访问(const)一条记录,
然后通过全表扫描访问a表(g表并没有和a表关联),然后通过a.order_no关联访问b表,然后通过b.sub_order_no关联访问 c表.....最后一直关联访问到d表。
疑问1:为什么这里g表不需要同其他表关联,这里是b表和其他表的左连接查询,如果g表不同其他表关联,怎么知道g表相关的列是应该输出null值,还是输出具体的某个值呢?
答:答案在where条件,where 条件中有 g.shop_no = 'xxxxxxx' 的过滤条件(shop_no 为g表主键),所以最后要么结果为空,要么结果中关于g表的值,肯定都是g.shop_no = 'xxxxxxx' 这行的值
疑问2:为什么访问g表时 Extra 显示 Using temporary; Using filesort?
答:
执行计划普通版:
#表名做了脱敏处理
mysql> explain SELECT any_value(b.id) AS id, b.sub_order_no, any_value(b.order_no) AS order_no
-> , any_value(b.status) AS status, any_value(b.c_m_mount) AS c_m_mount
-> , any_value(b.c_delivery_m_fee) AS c_delivery_m_fee, any_value(b.c_i_mount) AS c_i_mount
-> , any_value(b.c_delivery_i_fee) AS c_delivery_i_fee, any_value(c.publish_id) AS publish_id
-> , any_value(c.publish_version_id) AS publish_version_id, any_value(c.product_version_id) AS product_version_id
-> , any_value(c.sku_id) AS sku_id, any_value(c.num) AS num
-> , any_value(d.delivery_no) AS delivery_no, any_value(d.delivery_status) AS delivery_status
-> , any_value(d.delivery_code) AS delivery_code, any_value(d.delivery_com) AS delivery_com
-> , any_value(h.pay_type) AS pay_type, any_value(h.pay_channel) AS pay_channel
-> , any_value(g.shop_no) AS shop_no, any_value(a.create_time) AS create_time
-> , any_value(t.id) AS user_id, any_value(e.imp_price) AS imp_price
-> , any_value(a.address) AS address, any_value(a.tmp_order_no) AS tmp_order_no
-> , any_value(g.shop_type) AS shop_type, any_value(t.usertype) AS source
-> , any_value(f.pd_type) AS pd_type, any_value(e.cost_price) AS cost_price
-> , any_value(e.market_price) AS market_price, any_value(f.source) AS product_source
-> FROM test_od_suborder b
-> LEFT JOIN test_od_order a ON a.order_no = b.order_no
-> LEFT JOIN test_od_order_detail c ON b.sub_order_no = c.sub_order_no
-> LEFT JOIN test_od_delivery d ON d.sub_order_no = b.sub_order_no
-> LEFT JOIN test_pd_product_standard e ON e.id = c.sku_id
-> LEFT JOIN test_pd_product f ON f.product_no = e.product_no
-> LEFT JOIN test_pd_shop g ON f.shop_no = g.shop_no
-> LEFT JOIN m_ac_pay h
-> ON h.order_no = b.order_no
-> AND h.direction = '01'
-> LEFT JOIN b_channel_user t ON ac_userid = a.user_id
-> WHERE a.is_delete = '0'
-> AND g.shop_no = 'xxxxxxx'
-> AND b.status IN ('1', '2', '3')
-> GROUP BY b.sub_order_no
-> ORDER BY any_value(a.create_time) DESC
-> LIMIT 10;
+----+-------------+-------+------------+--------+----------------------------------------------------+--------------------+---------+------------------------+-------+----------+---------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+----------------------------------------------------+--------------------+---------+------------------------+-------+----------+---------------------------------+
| 1 | SIMPLE | g | NULL | const | PRIMARY | PRIMARY | 130 | const | 1 | 100.00 | Using temporary; Using filesort |
| 1 | SIMPLE | a | NULL | ALL | PRIMARY | NULL | NULL | NULL | 82171 | 10.00 | Using where |
| 1 | SIMPLE | b | NULL | ref | sub_order_no,idx_status_orderno,idx_orderno_status | idx_orderno_status | 163 | fd_mall.a.order_no | 1 | 96.17 | Using index condition |
| 1 | SIMPLE | c | NULL | ref | sub_order_no | sub_order_no | 163 | fd_mall.b.sub_order_no | 1 | 100.00 | NULL |
| 1 | SIMPLE | e | NULL | eq_ref | PRIMARY,product_no | PRIMARY | 130 | fd_mall.c.sku_id | 1 | 100.00 | Using where |
| 1 | SIMPLE | f | NULL | eq_ref | PRIMARY,shop_no | PRIMARY | 202 | fd_mall.e.product_no | 1 | 5.00 | Using where |
| 1 | SIMPLE | h | NULL | ref | order_no,idx_orderno_amount_paychannel | order_no | 163 | fd_mall.b.order_no | 1 | 100.00 | Using where |
| 1 | SIMPLE | t | NULL | ref | ac_userid | ac_userid | 163 | fd_mall.a.user_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | d | NULL | ref | sub_order_no | sub_order_no | 131 | fd_mall.b.sub_order_no | 1 | 100.00 | Using where |
+----+-------------+-------+------------+--------+----------------------------------------------------+--------------------+---------+------------------------+-------+----------+---------------------------------+
9 rows in set, 1 warning (0.01 sec)
json版(explain format = json select ....;)
|
"query_block":
"select_id": 1,
"cost_info":
"query_cost": "32590.78"
,
"ordering_operation":
"using_filesort": true,
"grouping_operation":
"using_temporary_table": true,
"using_filesort": false,
"nested_loop": [
"table":
"table_name": "g",
"access_type": "const",
"possible_keys": [
"PRIMARY"
],
"key": "PRIMARY",
"used_key_parts": [
"shop_no"
],
"key_length": "130",
"ref": [
"const"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 1,
"filtered": "100.00",
"cost_info":
"read_cost": "0.00",
"eval_cost": "0.10",
"prefix_cost": "0.00",
"data_read_per_join": "7K"
,
"used_columns": [
"shop_no",
"shop_type"
]
,
"table":
"table_name": "a",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows_examined_per_scan": 82171,
"rows_produced_per_join": 8217,
"filtered": "10.00",
"cost_info":
"read_cost": "8381.14",
"eval_cost": "821.71",
"prefix_cost": "9202.85",
"data_read_per_join": "5M"
,
"used_columns": [
"order_no",
"tmp_order_no",
"create_time",
"address",
"user_id",
"is_delete"
],
"attached_condition": "((`fd_mall`.`a`.`is_delete` = '0') and (`fd_mall`.`a`.`order_no` is not null))"
,
"table":
"table_name": "b",
"access_type": "ref",
"possible_keys": [
"sub_order_no",
"idx_status_orderno",
"idx_orderno_status"
],
"key": "idx_orderno_status",
"used_key_parts": [
"order_no"
],
"key_length": "163",
"ref": [
"fd_mall.a.order_no"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 7903,
"filtered": "96.18",
"index_condition": "((`fd_mall`.`b`.`status` in ('1','2','3')) and (`fd_mall`.`a`.`order_no` = `fd_mall`.`b`.`order_no`))",
"cost_info":
"read_cost": "2054.28",
"eval_cost": "790.31",
"prefix_cost": "12078.84",
"data_read_per_join": "6M"
,
"used_columns": [
"id",
"sub_order_no",
"order_no",
"c_m_mount",
"c_i_mount",
"c_delivery_m_fee",
"c_delivery_i_fee",
"status"
]
,
"table":
"table_name": "c",
"access_type": "ref",
"possible_keys": [
"sub_order_no"
],
"key": "sub_order_no",
"used_key_parts": [
"sub_order_no"
],
"key_length": "163",
"ref": [
"fd_mall.b.sub_order_no"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 7903,
"filtered": "100.00",
"cost_info":
"read_cost": "1975.78",
"eval_cost": "790.31",
"prefix_cost": "14844.93",
"data_read_per_join": "40M"
,
"used_columns": [
"id",
"sub_order_no",
"publish_id",
"publish_version_id",
"product_version_id",
"sku_id",
"num"
]
,
"table":
"table_name": "e",
"access_type": "eq_ref",
"possible_keys": [
"PRIMARY",
"product_no"
],
"key": "PRIMARY",
"used_key_parts": [
"id"
],
"key_length": "130",
"ref": [
"fd_mall.c.sku_id"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 7903,
"filtered": "100.00",
"cost_info":
"read_cost": "7723.11",
"eval_cost": "790.31",
"prefix_cost": "23358.35",
"data_read_per_join": "45M"
,
"used_columns": [
"id",
"product_no",
"imp_price",
"market_price",
"cost_price"
],
"attached_condition": "(`fd_mall`.`e`.`id` = `fd_mall`.`c`.`sku_id`)"
,
"table":
"table_name": "f",
"access_type": "eq_ref",
"possible_keys": [
"PRIMARY",
"shop_no"
],
"key": "PRIMARY",
"used_key_parts": [
"product_no"
],
"key_length": "202",
"ref": [
"fd_mall.e.product_no"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 395,
"filtered": "5.00",
"cost_info":
"read_cost": "7182.06",
"eval_cost": "39.52",
"prefix_cost": "31330.73",
"data_read_per_join": "1M"
,
"used_columns": [
"product_no",
"source",
"shop_no",
"pd_type"
],
"attached_condition": "((`fd_mall`.`f`.`shop_no` = 'GYS100195') and (`fd_mall`.`f`.`product_no` = `fd_mall`.`e`.`product_no`))"
,
"table":
"table_name": "h",
"access_type": "ref",
"possible_keys": [
"order_no",
"idx_orderno_amount_paychannel"
],
"key": "idx_orderno_amount_paychannel",
"used_key_parts": [
"order_no"
],
"key_length": "163",
"ref": [
"fd_mall.b.order_no"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 395,
"filtered": "100.00",
"cost_info":
"read_cost": "391.75",
"eval_cost": "39.52",
"prefix_cost": "31761.99",
"data_read_per_join": "564K"
,
"used_columns": [
"pay_no",
"order_no",
"direction",
"pay_type",
"pay_channel"
],
"attached_condition": "<if>(is_not_null_compl(h), (`fd_mall`.`h`.`direction` = '01'), true)"
,
"table":
"table_name": "t",
"access_type": "ref",
"possible_keys": [
"ac_userid"
],
"key": "ac_userid",
"used_key_parts": [
"ac_userid"
],
"key_length": "163",
"ref": [
"fd_mall.a.user_id"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 405,
"filtered": "100.00",
"cost_info":
"read_cost": "382.46",
"eval_cost": "40.51",
"prefix_cost": "32184.96",
"data_read_per_join": "2M"
,
"used_columns": [
"id",
"usertype",
"ac_userid"
]
,
"table":
"table_name": "d",
"access_type": "ref",
"possible_keys": [
"sub_order_no"
],
"key": "sub_order_no",
"used_key_parts": [
"sub_order_no"
],
"key_length": "131",
"ref": [
"fd_mall.b.sub_order_no"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 481,
"filtered": "100.00",
"cost_info":
"read_cost": "357.63",
"eval_cost": "48.19",
"prefix_cost": "32590.78",
"data_read_per_join": "3M"
,
"used_columns": [
"delivery_no",
"sub_order_no",
"delivery_code",
"delivery_status",
"delivery_com"
],
"attached_condition": "<if>(is_not_null_compl(d), (`fd_mall`.`d`.`sub_order_no` = `fd_mall`.`b`.`sub_order_no`), true)"
]
|
以上是关于一个奇怪的执行计划,关联查询中一个表未跟其他任何表关联的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 优化——奇怪的执行计划左加入一个不相关的子查询
数栈技术分享:解读MySQL执行计划的type列和extra列