博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sql优化(三)
阅读量:7095 次
发布时间:2019-06-28

本文共 2703 字,大约阅读时间需要 9 分钟。

hot3.png

好久没有准备sql优化的内容了。

5 子查询优化【优化※※※※】

子查询因为它的高可读和使用习惯,是我们的程序中常用的一种写法,但是其实它的效率并不高

举例子说明,查询在部门d005的员工信息

SELECT * from employees where emp_no in (SELECT emp_no FROM `dept_emp` where dept_no='d005')

执行时间1.4s,执行结果85707条。

查看执行计划

explain extended SELECT * from employees where emp_no in (SELECT emp_no FROM `dept_emp` where dept_no='d005');

1	PRIMARY	employees	ALL					300473	100	Using where2	DEPENDENT SUBQUERY	dept_emp	unique_subquery	PRIMARY,emp_no,dept_no	PRIMARY	16	func,const	1	100	Using index; Using where

居然还走了依赖子查询,效率更低啊。

换成多表查询吧(多表查询和join on, join using的效率是一样的 

select e.* from employees e,dept_emp d where d.emp_no=e.emp_no and d.dept_no='d005'

查询结果85707条,查询时间0.294s,速度快乐很多嘛

查看执行计划

explain EXTENDED select e.* from employees e,dept_emp d where d.emp_no=e.emp_no and d.dept_no='d005';

1	SIMPLE	d	ref	PRIMARY,emp_no,dept_no	dept_no	12	const	149978	100	Using where; Using index1	SIMPLE	e	eq_ref	PRIMARY	PRIMARY	4	employees.d.emp_no	1	100

做个试验,调换下where的顺序,看看mysql是否会自动优化

执行下面的执行计划

explain EXTENDED select e.* from employees e,dept_emp d where d.dept_no='d005' and  d.emp_no=e.emp_no ;

1	SIMPLE	d	ref	PRIMARY,emp_no,dept_no	dept_no	12	const	149978	100	Using where; Using index1	SIMPLE	e	eq_ref	PRIMARY	PRIMARY	4	employees.d.emp_no	1	100

执行计划是一样的,看来mysql内部的优化器已经自动做了优化

再换一种写法,看看能否优化,使用一张临时表

select e.* from employees e ,(SELECT emp_no FROM `dept_emp` where dept_no='d005') t where t.emp_no=e.emp_no;

执行时间0.26s,共85707条结果

查看执行计划 

EXPLAIN EXTENDED select e.* from employees e ,(SELECT emp_no FROM `dept_emp` where dept_no='d005') t where t.emp_no=e.emp_no;

1	PRIMARY	
ALL 85707 100 1 PRIMARY e eq_ref PRIMARY PRIMARY 4 t.emp_no 1 100 2 DERIVED dept_emp ref dept_no dept_no 12 149978 100 Using where; Using index

 

 6 like的优化【优化※※】

mysql中貌似对like的话的索引支持不好,所以对大表一个字段做like操作的话,即使做了索引页不定会走到

直接上实验结果

explain SELECT * FROM `employees` where first_name = 'Guoxiang';

employees表上的firstname是有个一索引的,看执行计划也是可以走到索引的

1	SIMPLE	employees	ref	index_firstName	index_firstName	44	const	255	Using where

 如果like的是全字段,或者like字段的后半部分貌似都能走到索引。。。 

explain SELECT * FROM `employees` where first_name like 'Guoxiang';

1	SIMPLE	employees	range	index_firstName	index_firstName	44		255	Using where

explain SELECT * FROM `employees` where first_name like 'Guo%';

1	SIMPLE	employees	range	index_firstName	index_firstName	44		503	Using where

如果是查询前半个字段就不行了

explain SELECT * FROM `employees` where first_name like '%xiang';

1	SIMPLE	employees	ALL					300473	Using where

对于like的解决方案,网上倒是有些说法

MYISAM引擎 英文的直接全文索引-中文的分词索引,用以取代LIKE
就是新建一个字段,存储原是字段的反向内容,然后搜索时,就可以倒过来搜索了。例如: like '%str‘ 可以改成like 'rts%'

总结一下,子查询的效率不高,一般可以用多表连接的来替换一下以提高效率。like也不是不走索引的,但是like前置部分是不走索引的,需要用全文索引或者倒置查询来替换下jiej

转载于:https://my.oschina.net/zimingforever/blog/66600

你可能感兴趣的文章
Javascript:DOM表格操作
查看>>
解决WCF传输大数据量时出错并提示:远程主机强迫关闭了一个现有的连接
查看>>
蓝桥杯-波动数列
查看>>
图片理论基础
查看>>
HDU4300 Clairewd’s message
查看>>
【原】iOS学习之图片拉伸处理(类似qq的气泡)
查看>>
postman抓包
查看>>
最大稳定极值区域(MSER)检测
查看>>
如何解决CorelDRAW中尖突问题
查看>>
Javascript实现Web颜色值转换
查看>>
拼接日期填写表单
查看>>
工控系统安全问题汇总(一)
查看>>
4、SpringBoot------邮件发送(2)
查看>>
java创建二叉树并递归遍历二叉树
查看>>
JSON必知必会
查看>>
安全站点导航
查看>>
Oracle Job
查看>>
收集一些有意思的ASCII程序注释(持续收集中,希望大家踊跃贡献)
查看>>
做网站的各种推荐网
查看>>
leetcode 10. 正则表达式匹配
查看>>