查询优化、索引优化、库表结构优化齐头并进才能保证出一条高效的查询策略。
1、不要向数据库请求不需要的数据
2、确定mysql 是否扫描了额外的记录
1、衡量 mysql 开销的三个指标
响应时间
扫描行数
返回行数
在explain 的type 列反应了访问类型:全表扫描、索引扫描、范围扫描、唯一索引查询、常用引用。速度由慢到快。
在不确定的情况下加一个合理的索引 能够有效的减少我们扫描的行数,返回我们需要的数据。
2、mysql 使用三种方式应用where
3、如果需要扫描大量的数据来返回少量的数据我们的优化方法 为
- 使用索引覆盖扫描,把需要用的列到放到索引中,这个存储引擎无需回表获取对应行就可以返回结果了
- 改变库表结构(使用单独的汇总表)
- 重写这个复杂的从查询,让mysql 优化器能够以更优化的方式来致行这条sql
3、重构查询方式
1、一个复杂的查询还是多个简单的查询
2、切分查询
将一个大的查询拆分为小的查询,每个查询功能都一样,只完成一小部分数据
3、分解关联查询
阿里巴巴开发手册不建议使用超过三个join连接。可以将一个复杂的关联查询查分成简单的单边查询,在应用程序中关联
优势:
让缓存的效率更高
单个查询减少锁的竞争
IN()代替关联查询可以按ID的顺序致行,比随机的致行效率要高的多
4、查询致行基础
1,mysql 发送一个请求后都做了哪些事
2、mysql 能够处理的优化类型
5、索引优化
1 索引的优点 :
提高少量数据的获取 / 减少扫描的行数/检索速度
2 索引的缺点 :
- 占用存储空间
- 多个索引耗费索引的挑选时间
- 降低写操作的性能,需要实时维护索引
- 并发情况下索引的维护高度复杂
3 什么时候不使用索引 :
- 数据的重复度高 , 即:选择率高
- 选择率高于 10%, 建议不考虑使用这个索引
- 表的数据量较少
4 使用索引的条件
- 一个经常查询的字段 大于,小于,或者 in(),模糊查询
- 主键和外键一般需要索引
- sql 执行查询的频率非常高
- 只利用索引来读取数据 select 列为索引列是不扫描全表的
5 索引失效情况
- like "%name" 或者 like "%name%" 这种查询会导致索引失效全表扫描。但是可以使用 like "name%"
- 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- not in ,not exist.
- 查询条件上不能有运算 select * from test where id-1=9;
- 使用操作符对索引的影响 !=
6、子查询优化
用子查询效率确实更低,因为这里每次子查询每次都需要建立临时表,它会把结果集都存到临时表,这样外部查询select count(*)又重新扫描一次临时表,导致用时更长,扫描效率更低
可以优化那些格式的子查询
带有DISTINCT、ORDERBY、LIMIT操作的简单SELECT查询中的子查询
MySQL不支持对如下情况的子查询进行优化:
带有UNION操作。
带有GROUPBY、HAVING、聚集函数。
使用ORDERBY中带有LIMIT。
内表、外表的个数超过MySQL支持的最大表的连接数。
支持那些子查询优化技术
支持那类型的子查询进行优化
7、视图优化
8、sql 优化
1、ORDER BY 优化技术
在索引列上进行排序操作, MySQL 支持利用索引进行排序优化
2、MySQL 的 LIMIT 优化技术
3、in子查询查询优化
SELECT a.* FROM tb_article as a
WHERE a.cate_id in (
SELECT b.cate_id FROM tb_article_cate b WHERE parent_id =10
)
- mysql 不会按上面的先查询子查询和语句 会将相关联的外表压到子查询中
- 需要关联外表所以mysql 无法先执行这个子查询 mysql执行流程为
SELECT a.* FROM tb_article as a
where EXISTS(
SELECT b.* FROM tb_article_cate b WHERE parent_id =10
AND a.cate_id = b.cate_id
)
通过 EXPLAIN 分析SQL 语句:是对主表进行了全表扫描 在根据返回的 id逐个查询,如果主表数据量非常大查询效率是非常慢的。
用内连接优化子查询
inner join 在执行的时候回自动选择最小的表做基础表,效率高,不会进行全表扫描
EXPLAIN SELECT a.* FROM tb_article as a
INNER JOIN tb_article_cate b USING(cate_id)
WHERE b.parent_id =10
4、union的限制
如果将两个子查询中的结果合并取前20条 会将两个表中的所有数据放到临时表中在取前20条,查询效率是很慢的,但是我们去两个表中各自的前20条在合并临时表中只放人了40条数据在取前20条
可以优化可以优化什么格式的子查询什么格式的子查询
可以优化什么格式的子查询
可以优化什么可以优化什么格式的子查询格式的子查询