加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

发布时间:2019-07-25 23:34:29 所属栏目:评测 来源:Java架构师笔记
导读:1、LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。 好吧,可能90%以上的 DBA

去掉 exists 更改为 join,能够避免嵌套子查询,将执行时间从1.93秒降低为1毫秒。

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

新的执行计划:

+----+-------------+-------+--------+ -----+------------------------------------------+---------+ -----+------+ -----+

| id | select_type | table |type| possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+-------+--------+ -----+------------------------------------------+---------+ -----+------+ -----+

| 1 | SIMPLE | m | ref | | idx_message_info | 122 | const | 1 | Using index condition |

| 1 | SIMPLE | n | eq_ref | | PRIMARY | 122 | ighbor_id | 1 | Usingwhere|

| 1 | SIMPLE | sra | ref | | idx_user_id | 123 | const | 1 | Usingwhere|

+----+-------------+-------+--------+ -----+------------------------------------------+---------+ -----+

6、条件下推

外部查询条件不能够下推到复杂的视图或子查询的情况有:

聚合子查询;

含有 LIMIT 的子查询;

UNION 或 UNION ALL 子查询;

输出字段中的子查询;

如下面的语句,从执行计划可以看出其条件作用于聚合子查询之后:

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

确定从语义上查询条件可以直接下推后,重写如下:

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

执行计划变为:

+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+

| id | select_type | table |type| possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+

| 1 | SIMPLE | operation | ref | idx_4 | idx_4 | 514 | const | 1 | Usingwhere; Using index |

+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+

7、提前缩小范围

先上初始 SQL 语句:

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

该SQL语句原意是:先做一系列的左连接,然后排序取前15条记录。从执行计划也可以看出,最后一步估算排序记录数为90万,时间消耗为12秒。

+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+

| id | select_type | table |type| possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+

| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 909119 | Usingwhere; Using temporary; Using filesort |

| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | o.uid | 1 | NULL |

| 1 | SIMPLE | p | ALL | PRIMARY | NULL | NULL | NULL | 6 | Usingwhere; Using join buffer (Block Nested Loop) |

+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+

由于最后 WHERE 条件以及排序均针对最左主表,因此可以先对 my_order 排序提前缩小数据量再做左连接。SQL 重写后如下,执行时间缩小为1毫秒左右。

Java架构师笔记丨常见的错误 SQL 用法,你中招了吗?

再检查执行计划:子查询物化后(select_type=DERIVED)参与 JOIN。虽然估算行扫描仍然为90万,但是利用了索引以及 LIMIT 子句后,实际执行时间变得很小。复制代码

+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+

| id | select_type | table |type| possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+

| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 15 | Using temporary; Using filesort |

| 1 | PRIMARY | u | eq_ref | PRIMARY | PRIMARY | 4 | o.uid | 1 | NULL |

| 1 | PRIMARY | p | ALL | PRIMARY | NULL | NULL | NULL | 6 | Usingwhere; Using join buffer (Block Nested Loop) |

| 2 | DERIVED | o | index | NULL | idx_1 | 5 | NULL | 909112 | Usingwhere|

+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+

8、中间结果集下推

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读