sql的一些优化建议

sql的索引设计和表优化都是非常重要的点,好的sql可以极大的减低成本,提高用户体验,而一条不好的sql就有可能让CPU100%,下面列举了一些常写的sql注意事项。

一、少用join之类联表查询

1,当数据量增加的时候,join会导致查询性能下降
2,分布式数据,分表分库比较多,join跨库性能表现不佳
3,join连接多个表,当一个表改动的时候,改动起来不方便

二、一些用不到索引的查询

1.负向查询一般用不到索引
select * from name != 'XXX';

2.强制类型转换用不到索引
select * from phone = 18999999999
phone是string类型,如果查询的时候没有加双引号,那么会导致全表烧苗,使用不到索引

3.复合索引左前缀
复合索引(uid,name)
select * from uid = 1 and name = 'xxx'; //使用到索引
select * from name = 'xxx' //没有使用索引
select * from name = 'xxx' and uid = 1 //使用到索引

4.null查询
索引不存null的值,所以值为null是无法使用索引的
select * from name is null; // 无法使用索引

5.前导模糊查询无法使用索引
select * from name like '%XX'; // 无法使用索引

三、优化查询

   sql语句的优化,与之相关的东西说多不多,说少不少,其中非常重要的一点就是索引的运用。
对于索引,也许我们要从索引的原理和结构讲起,讲到B+tree,hash等,讲到这些估计又要科普一下
时间复杂度(O),讲到复杂度,又要从操作数来讲了,所以这里就不讲那么多,只讲基本的原理。

(1) 磁盘IO

一个数据库必须保证数据能随机随时读取,我们如果需要优化读取速率必须要明白数据是如何流动的。
 这就涉及到磁盘IO了。
 从数据库里面到数据的显示,并不是直接从数据库里面把数据拿到页面上的,而是需要经历一系列过
 程。
    
 
 现在讲一下计算机的运行原理:计算机运行自然是非常复杂的,但是其过程可以简单的介绍一下。
数据通过IO桥从磁盘里刷到主存中,在从主存中刷到寄存器中,最后在处理器中执行。
 
 mysql在执行的过程中,会先从mysql的缓冲区中读取,如果缓冲区读取不到的话就会尝试从内存中加
 载数据页,如果内存中也无法读取成功的话,就会尝试随机IO从磁盘中读取数据。
 

 

(2) 索引的设计

索引的设计没有想象中的难,只需掌握规律,设计一个不错的索引还是可行的。

磁盘IO中讲到了,数据的流动方向,每一层需要消耗的时间成本也是不同,数据缓存取数据,
速度非常快。而在磁盘中进行IO的话,需要付出很大的时间成本,但是如果数据是顺序读取的话
速度可以达到磁盘随机读取的几千,上万倍。
过滤因子
什么是过滤因子:
过滤因子可以理解为字段被过滤的概率 比如:性别的过滤因子是50%;
字段 过滤因子
name 0.1%
age 10%
sex 50%
对于不同的字段有不同的过滤因子,过滤因子越小,过滤的数据越多,查询的越少,在表user中,如果选
择sex为索引,那么将不是很好的选择,最直观的的印象就是sex这个字段,过滤不了多少数据,
扫描行数依旧非常大。
我们如果以name为索引,将会是一个更好的选择。或者可以建立一个组合索引(name,age,sex)

三星索引
《数据库索引与设计》一文中,三星索引指的是:
第一星:WHERE 条件等值作为组合索引最开头的列。
第二星:将order by加入索引中
第三星:将查询语句剩余的列加入索引中

对于如下语句:
select name,sex,age,id_card from user where name = 'xxx' and age = xx order by phone;
满足第一星的索引:(name,age),(age,name)
满足第二星的索引:(name,age,phone)(age,name,phone)
满足第三星的索引:(name,age,phone,id_card)(age,name,phone,id_card)

索引满足了三星索引的要求可以算的是优质索引,查询速率也会非常不错,不过就算不能满足三星,也尽可能满足多的星。

总结

说了那么多,其实索引的设计只要遵循一定的规律,还是不是很难的。
总而言之:索引的设计和sql语句的写法都息息相关,我们不仅仅要考虑
表的设计,也要考虑怎么写sql才能更好的设计索引。

你可能感兴趣的:(sql的一些优化建议)