关于Mysql SQL优化的总结,持续更新中
2018-07-25 23:17
627 查看
SQL优化的思路:
1.优化更需要优化的sql;
2.定位优化对象的性能瓶颈:优化前需了解查询的瓶颈是IO还是CPU,可通过PROFILING很容易定位查询的瓶颈。
3.明确优化目标;
4.从Explain入手;
5.多使用profile;
SQL优化的基本原则:
1.永远用小结果集驱动大结果集;
From子句中sql解析顺序为从右向左,执行时会以最左边的表为基础表循环与右边表数据做笛卡尔积,所以以小结果集驱动能减少循环次数,从而减少对被驱动结果集的访问,从而减少被驱动表的锁定。
2.尽可能在索引中完成排序;
排序算法有两种:a.查出排序字段和行指针,排序,再通过行指针获得行数据所需列,返回结果集;b.取出所有排序列数据,在排序缓冲区中排完序直接返回结果集。
索引排序是利用索引的有序性对数据排序的。
3.只取出子集需要的colums
4.仅仅使用最有效的过滤条件;
5.尽可能避免复杂的Join和子查询;
索引的好处:
(1).提高数据检索效率,降低数据库的IO成本。
(2).降低数据排序成本:要求排序字段和索引键字段一致。
(3).降低数据分组成本:因为分组之前会先排序,同意如果分组字段与索引字段一致,会降低分组消耗的成本。
索引的弊端:
(1).索引是独立于基础数据的数据库对象,因此它会占用存储空间。
(2).数据新增、更新会导致索引的同步更新,所以会增加数据新增、更新所消耗的成本。
判断是否需要创建索引:
(1).较为频繁的作为查询条件的字段需要创建索引
(2). 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;
(3).更新非常频繁的字段不适合创建索引;
(4).不会出现在where子句中的字段不要创建索引;
1、只要能满足你的需求,应尽可能使用更小的数据类型:例如使用MEDIUMINT代替INT
2、尽量把所有的列设置为NOT NULL,如果你要保存NULL,手动去设置它,而不是把它设为默认值。
3、尽量少用VARCHAR、TEXT、BLOB类型
4、如果你的数据只有你所知的少量的几个。最好使用ENUM类型
5、正如graymice所讲的那样,建立索引。
SQL编写注意事项:
1.原则1、仅列出需要查询的字段,这对速度不会明显的影响,主要是考虑节省应用程序服务器的内存。
2.原则2、尽量避免在列上做运算,这样导致索引失效。
3.原则3、使用JOIN 时候,应该用小的结果驱动大的结果(left join 左边表结果尽量小 如果有条件应该放到左边先处理,right join 同理反向),同事尽量把牵涉到多表联合的查询拆分多个query(多个连表查询效率低,容易到之后锁表和阻塞)。
4.原则4、注意LIKE 模糊查询的使用, 避免使用 %% ,可以使用 后面带% ,双%是不走索引的。
5.原则5、使用批量插入节省交互 (当如如果使用存储过程来处理批量的sql 各种逻辑是更好的选择)。
6.原则6、limit的基数比较大时使用between。
7.原则7、不要使用rand函数获取多条随机记录。
8.原则8、避免使用NULL。
9.原则9. 不要使用 count(id) 使用 count(*)。
10.原则10、不要做无谓的排序操作,而应该使用索引列完成排序。即order排序列必为索引
11.原则11、where条件中,过滤量最大的条件放在where子句最后;
12.原则12、在索引列上使用计算、改变索引列的类型(不匹配的数据类型)、在索引列上使用!=将放弃索引;
13.运算符效率:exists高于in高于or,(not exists高于not in); IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子句中应该包含索引。用union 连接
14.避免在索引列上使用is null和is not null;
15.用union-all替代union;
16.采用as 别名 采用绑定变量有助于提高效率;
17.使用函数=将放弃索引;
18/避免使用HAVING字句
B-tree 索引和 hash索引
Innodb和MyISAM默认的索引是Btree索引;而Mermory默认的索引是Hash索引。
hash索引
所谓Hash索引,当我们要给某张表某列增加索引时,将这张表的这一列进行哈希算法计算,得到哈希值,排序在哈希数组上。所以Hash索引可以一次定位,其效率很高,而Btree索引需要经过多次的磁盘IO,但是innodb和myisam之所以没有采用它,是因为它存在着好多缺点:
1、因为Hash索引比较的是经过Hash计算的值,所以只能进行等式比较,不能用于范围查询
1、每次都要全表扫描
2、由于哈希值是按照顺序排列的,但是哈希值映射的真正数据在哈希表中就不一定按照顺序排列,所以无法利用Hash索引来加速任何排序操作
3、不能用部分索引键来搜索,因为组合索引在计算哈希值的时候是一起计算的。
4、当哈希值大量重复且数据量非常大时,其检索效率并没有Btree索引高的。
Btree索引(单独文章描述)
至于Btree索引,它是以B+树为存储结构实现的。
但是Btree索引的存储结构在Innodb和MyISAM中有很大区别。
所以我们经常会说MyISAM中数据文件和索引文件是分开的。
因此MyISAM的索引方式也称为非聚集,Innodb的索引方式成为聚集索引。
至于辅助索引,类似于主索引,唯一区别就是主索引上的值不能重复,而辅助索引可以重复。
1.优化更需要优化的sql;
2.定位优化对象的性能瓶颈:优化前需了解查询的瓶颈是IO还是CPU,可通过PROFILING很容易定位查询的瓶颈。
3.明确优化目标;
4.从Explain入手;
5.多使用profile;
SQL优化的基本原则:
1.永远用小结果集驱动大结果集;
From子句中sql解析顺序为从右向左,执行时会以最左边的表为基础表循环与右边表数据做笛卡尔积,所以以小结果集驱动能减少循环次数,从而减少对被驱动结果集的访问,从而减少被驱动表的锁定。
2.尽可能在索引中完成排序;
排序算法有两种:a.查出排序字段和行指针,排序,再通过行指针获得行数据所需列,返回结果集;b.取出所有排序列数据,在排序缓冲区中排完序直接返回结果集。
索引排序是利用索引的有序性对数据排序的。
3.只取出子集需要的colums
4.仅仅使用最有效的过滤条件;
5.尽可能避免复杂的Join和子查询;
索引的好处:
(1).提高数据检索效率,降低数据库的IO成本。
(2).降低数据排序成本:要求排序字段和索引键字段一致。
(3).降低数据分组成本:因为分组之前会先排序,同意如果分组字段与索引字段一致,会降低分组消耗的成本。
索引的弊端:
(1).索引是独立于基础数据的数据库对象,因此它会占用存储空间。
(2).数据新增、更新会导致索引的同步更新,所以会增加数据新增、更新所消耗的成本。
判断是否需要创建索引:
(1).较为频繁的作为查询条件的字段需要创建索引
(2). 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;
(3).更新非常频繁的字段不适合创建索引;
(4).不会出现在where子句中的字段不要创建索引;
1、只要能满足你的需求,应尽可能使用更小的数据类型:例如使用MEDIUMINT代替INT
2、尽量把所有的列设置为NOT NULL,如果你要保存NULL,手动去设置它,而不是把它设为默认值。
3、尽量少用VARCHAR、TEXT、BLOB类型
4、如果你的数据只有你所知的少量的几个。最好使用ENUM类型
5、正如graymice所讲的那样,建立索引。
SQL编写注意事项:
1.原则1、仅列出需要查询的字段,这对速度不会明显的影响,主要是考虑节省应用程序服务器的内存。
2.原则2、尽量避免在列上做运算,这样导致索引失效。
3.原则3、使用JOIN 时候,应该用小的结果驱动大的结果(left join 左边表结果尽量小 如果有条件应该放到左边先处理,right join 同理反向),同事尽量把牵涉到多表联合的查询拆分多个query(多个连表查询效率低,容易到之后锁表和阻塞)。
4.原则4、注意LIKE 模糊查询的使用, 避免使用 %% ,可以使用 后面带% ,双%是不走索引的。
5.原则5、使用批量插入节省交互 (当如如果使用存储过程来处理批量的sql 各种逻辑是更好的选择)。
6.原则6、limit的基数比较大时使用between。
原来语句:select * from admin order by admin_id limit 100000,10 优化为: select * from admin where admin_id between 100000 admin 100010 order by admin_id
7.原则7、不要使用rand函数获取多条随机记录。
原来语句: select * from admin order by rand() limit 20 优化为: select * from admin as t1 Join(select round(rand()*((select max(admin_id) from admin)-(select min(id) from admin))+(select min(id) from admin)) as id) as t2 where t1.id>=t2.id order by t1.id limit
8.原则8、避免使用NULL。
9.原则9. 不要使用 count(id) 使用 count(*)。
10.原则10、不要做无谓的排序操作,而应该使用索引列完成排序。即order排序列必为索引
11.原则11、where条件中,过滤量最大的条件放在where子句最后;
12.原则12、在索引列上使用计算、改变索引列的类型(不匹配的数据类型)、在索引列上使用!=将放弃索引;
13.运算符效率:exists高于in高于or,(not exists高于not in); IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子句中应该包含索引。用union 连接
14.避免在索引列上使用is null和is not null;
15.用union-all替代union;
16.采用as 别名 采用绑定变量有助于提高效率;
17.使用函数=将放弃索引;
18/避免使用HAVING字句
B-tree 索引和 hash索引
Innodb和MyISAM默认的索引是Btree索引;而Mermory默认的索引是Hash索引。
hash索引
所谓Hash索引,当我们要给某张表某列增加索引时,将这张表的这一列进行哈希算法计算,得到哈希值,排序在哈希数组上。所以Hash索引可以一次定位,其效率很高,而Btree索引需要经过多次的磁盘IO,但是innodb和myisam之所以没有采用它,是因为它存在着好多缺点:
1、因为Hash索引比较的是经过Hash计算的值,所以只能进行等式比较,不能用于范围查询
1、每次都要全表扫描
2、由于哈希值是按照顺序排列的,但是哈希值映射的真正数据在哈希表中就不一定按照顺序排列,所以无法利用Hash索引来加速任何排序操作
3、不能用部分索引键来搜索,因为组合索引在计算哈希值的时候是一起计算的。
4、当哈希值大量重复且数据量非常大时,其检索效率并没有Btree索引高的。
Btree索引(单独文章描述)
至于Btree索引,它是以B+树为存储结构实现的。
但是Btree索引的存储结构在Innodb和MyISAM中有很大区别。
所以我们经常会说MyISAM中数据文件和索引文件是分开的。
因此MyISAM的索引方式也称为非聚集,Innodb的索引方式成为聚集索引。
至于辅助索引,类似于主索引,唯一区别就是主索引上的值不能重复,而辅助索引可以重复。
相关文章推荐
- 本文主要总结在微博关于mysql的优化(将会持续更新)
- MySQL系统配置参数优化总结【持续更新中】
- mysql优化 -- 持续总结更新
- Mysql实用SQL语句总结(持续更新)
- Mysql跨表更新 多表update sql语句总结
- mysql常用总结《持续更新......》
- mysql关于日期的问题(合集,持续更新中:2018.03.26)
- 【数据库】oracle常用sql总结(持续更新中)
- MYSQL语句调优:SQL优化总结
- MYSQL常用SQL语句(持续更新)
- erlang程序优化点的总结(持续更新)
- MySql 优化小技巧总结(不断更新中...)
- 关于过去工作的一些总结:常用sql语句以及数据库查询优化
- mysql查询优化(持续更新中)
- BUG记录之——关于AS的一些红buffer总结(持续更新中)
- 关于sql优化的一个小总结
- 【MYSQL】某些有用的sql【持续更新中】
- SQL语句常见问题的总结(持续更新)
- mysql 有用sql总结(不断更新中...)
- 【小平工作日志】Mysql 相关sql语句(新建、更新等)持续更新中……