1.优化更须要优化的sql;
2.定位优化对象的性能瓶颈:优化前需了解查询的瓶颈是IO仍是CPU,可经过PROFILING很容易定位查询的瓶颈。
3.明确优化目标;
4.从Explain入手;
5.多使用profile;算法
1.永远用小结果集驱动大结果集;
From子句中sql解析顺序为从右向左,执行时会以最左边的表为基础表循环与右边表数据作笛卡尔积,因此以小结果集驱动能减小循环次数,从而减小对被驱动结果集的访问,从而减小被驱动表的锁定。
2.尽量在索引中完成排序;
排序算法有两种:a.查出排序字段和行指针,排序,再经过行指针得到行数据所需列,返回结果集;b.取出全部排序列数据,在排序缓冲区中排完序直接返回结果集。
索引排序是利用索引的有序性对数据排序的。
3.只取出子集须要的colums
4.仅仅使用最有效的过滤条件;
5.尽量避免复杂的Join和子查询;sql
(1).提升数据检索效率,下降数据库的IO成本。
(2).下降数据排序成本:要求排序字段和索引键字段一致。
(3).下降数据分组成本:由于分组以前会先排序,赞成若是分组字段与索引字段一致,会下降分组消耗的成本。数据库
(1).索引是独立于基础数据的数据库对象,所以它会占用存储空间。
(2).数据新增、更新会致使索引的同步更新,因此会增长数据新增、更新所消耗的成本。数组
(1).较为频繁的做为查询条件的字段须要建立索引
(2). 惟一性太差的字段不适合单首创建索引,即便频繁做为查询条件;
(3).更新很是频繁的字段不适合建立索引;
(4).不会出如今where子句中的字段不要建立索引;
一、只要能知足你的需求,应尽量使用更小的数据类型:例如使用MEDIUMINT代替INT 二、尽可能把全部的列设置为NOT NULL,若是你要保存NULL,手动去设置它,而不是把它设为默认值。 三、尽可能少用VARCHAR、TEXT、BLOB类型 四、若是你的数据只有你所知的少许的几个。最好使用ENUM类型 五、正如graymice所讲的那样,创建索引。服务器
1.原则一、仅列出须要查询的字段,这对速度不会明显的影响,主要是考虑节省应用程序服务器的内存。
2.原则二、尽可能避免在列上作运算,这样致使索引失效。
3.原则三、使用JOIN 时候,应该用小的结果驱动大的结果(left join 左边表结果尽可能小 若是有条件应该放到左边先处理,right join 同理反向),同事尽可能把牵涉到多表联合的查询拆分多个query(多个连表查询效率低,容易到以后锁表和阻塞)。
4.原则四、注意LIKE 模糊查询的使用, 避免使用 %% ,可使用 后面带% ,双%是不走索引的。
5.原则五、使用批量插入节省交互 (当如若是使用存储过程来处理批量的sql 各类逻辑是更好的选择)。
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.原则七、不要使用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.原则八、避免使用NULL。
9.原则9. 不要使用 count(id) 使用 count(*)。
10.原则十、不要作无谓的排序操做,而应该使用索引列完成排序。即order排序列必为索引
11.原则十一、where条件中,过滤量最大的条件放在where子句最后;
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字句优化
Innodb和MyISAM默认的索引是Btree索引;而Mermory默认的索引是Hash索引。指针
hash索引
所谓Hash索引,当咱们要给某张表某列增长索引时,将这张表的这一列进行哈希算法计算,获得哈希值,排序在哈希数组上。因此Hash索引能够一次定位,其效率很高,而Btree索引须要通过屡次的磁盘IO,可是innodb和myisam之因此没有采用它,是由于它存在着好多缺点:
一、由于Hash索引比较的是通过Hash计算的值,因此只能进行等式比较,不能用于范围查询
一、每次都要全表扫描
二、因为哈希值是按照顺序排列的,可是哈希值映射的真正数据在哈希表中就不必定按照顺序排列,因此没法利用Hash索引来加速任何排序操做
三、不能用部分索引键来搜索,由于组合索引在计算哈希值的时候是一块儿计算的。
四、当哈希值大量重复且数据量很是大时,其检索效率并无Btree索引高的。code
Btree索引(单独文章描述) 至于Btree索引,它是以B+树为存储结构实现的。 可是Btree索引的存储结构在Innodb和MyISAM中有很大区别。 因此咱们常常会说MyISAM中数据文件和索引文件是分开的。 所以MyISAM的索引方式也称为非汇集,Innodb的索引方式成为汇集索引。 至于辅助索引,相似于主索引,惟一区别就是主索引上的值不能重复,而辅助索引能够重复。