您的位置:首页 > 数据库 > MySQL

Java面试之Mysql语句优化

2020-06-24 04:30 330 查看

优化sql语句–01
现在有一条语句
已知数据表的主键字段为id,这条sql有严重的性能问题,请写下优化后的sql语句,并分析问题产生的
原因。
我们创建一个类似的表来分析一下。
新建一个带主键和一般字段的表,再插入若干条数据。
查看一下这条语句的执行计划
得到结果集里面,分析其中的几个重要字段。
select_type
查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询
1、SIMPLE:简单的select查询,查询中不包含子查询或者union
2、PRIMARY:查询中包含任何复杂的子部分,最外层查询则被标记为primary
3、SUBQUERY:在select 或 where列表中包含了子查询
4、DERIVED:在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查
询,把结果放在零时表里
5、UNION:若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询
中,外层select将被标记为derived
6、UNION RESULT:从union表获取结果的select

select * from user limit 1000000, 10;
drop table test_user;
create table test_user (
u_id varchar(20) primary key,
u_name varchar(36),
u_desc varchar(100)
)
insert into test_user values('asdb1', "哈哈", "按时缴费拉设计费1");
insert into test_user values('asdb2', "哈哈", "按时缴费拉设计费2");
insert into test_user values('asdb3', "哈哈", "按时缴费拉设计费3");
insert into test_user values('asdb4', "哈哈", "按时缴费拉设计费4");
insert into test_user values('asdb5', "哈哈", "按时缴费拉设计费5");
insert into test_user values('asdb6', "哈哈", "按时缴费拉设计费6");
insert into test_user values('asdb7', "哈哈", "按时缴费拉设计费7");
insert into test_user values('asdb8', "哈哈", "按时缴费拉设计费8");
insert into test_user values('asdb9', "哈哈", "按时缴费拉设计费9");
insert into test_user values('asdb0', "哈哈", "按时缴费拉设计费0");
explain select * from test_user limit 1000000, 10;

``
**

优化sql语句–02:in 和 exists 的区别,如何优化

**
我们来看看这两个语句
他们的执行结果一致,查看执行计划也一致。

但这只是小数据量情况下的假象。
in: in是把外表和内表做hash连接,先查询内表,再把内表结果与外表匹配,他是先将数据督
导内存中,然后取与外表匹配。他要执行的次数是外表的长度*内表结果的长度。
exists: exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表
的查询使用的索引,他只需要执行的次数是外表的长度。
通过子查询返回的数据是否为null,如果不为null,那么就会将当前的数据加入结果集,因此我们
select * from a的时候,我们是从第一条数据开始执行的,每次执行都会去执行exists的子查询,如果
不为null就加入结果集,反之则不加入,直到最后执行完主查询为止。
关键在于使用的场景
使用in的场景:a表的数据大于b表的数据(关联查询后的数据)
使用 exists的场景:a表的数据小于b表的数据(关联查询后的数据)
如果数据量相同in和exists都可以使用
其实最好的优化是既不用 in 也不用 exists。

explain select a.* from test_user a where a.u_id between "asdb0" and "asdb9"
explain select a.* from test_user a where exists (
select 1 from test_user b where b.u_desc like '%按时%' and b.u_desc = a.u_desc)
explain select a.* from test_user a where a.u_desc in (
select b.u_desc from test_user b where b.u_desc like '%按时%' )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: