mysql 优化
mysql优化包括两方面,一方面是sql优化,另一方面是数据库配置优化;
一、sql优化
1.优化数据类型
①尽量将字段设置为 not null,如果你要保存NULL,手动去设置它,而不是把它设为默认值
②尽量可能的使用更小的字段,但也不要太过执着减小数据类型,要为以后的程序拓展预留一定的空间
③尽量少用VARCHAR、TEXT、BLOB类型
④如果你的数据只有你所知的少量的几个,最好使用ENUM类型
2.使用索引更快的来遍历表
3.在海量查询时尽量不进行格式转换
4.ORDER BY和GROPU BY使用ORDER BY和GROUP BY短语,任何一种索引都有助于SELECT的性能提高
5.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边
6.IN、OR子句常会使用工作表,导致索引失效。尽量避免在列上做运算,这样也会导致索引失效。如果不产生大量重复值,可以考虑把子句拆开,拆开的子句中应该包含索引
例子如下:
如果在fields1和fields2上同时建立了索引,fields1为主索引
①以下sql会用到索引
select * from tablename1 where fields1='value1' and fields2='value2'
②而以下sql不会用到索引
select * from tablename1 where fields1='value1' or fields2='value2'
③避免在列上做运算
原语句: select * from admin where year(admin_time)>2014
优化为: select * from admin where admin_time> '2014-01-01'
7.多表查询的优化原则:尽量将索引建立在(left join on/right join on ... +条件)条件语句中所涉及的字段上,且多表查询比单表查询更能体现索引的优势
8.索引建立原则:
①最好索引前缀不重复的某一列且索引越短越好
②索引建立在查询字段上,而不是显示字段
③索引应建立在那些将用于JOIN, WHERE判断和ORDER BY排序的字段上,尽量不要对数据库中某个含有大量重复的值的字段建立索引。
9.有些表如果经常insert,而较少select,就不用加索引了.不然每次写入数据都要重新改写索引,花费时间
10.仅列出需要查询的字段,这对速度不会明显的影响,主要是考虑节省应用程序服务器的内存
原来语句:select * from admin
优化为:select admin_id,admin_name,admin_password from admin
11.注意使用like模糊查询,避免使用%%,尽量在后面使用%,双%不走索引
12.使用批量插入节省交互
原来语句:
insert into admin(admin_name,admin_password) values ('test1','pass1');
insert into admin(admin_name,admin_password) values ('test2','pass2');
insert into admin(admin_name,admin_password) values ('test3','pass3');
优化为:
insert into admin(admin_name,admin_password) values('test1','pass1'),('test2','pass2'),('test3','pass3');
13.limit的基数比较大时,使用between
原来语句:select * from admin order by admin_id limit 100000,10
优化为: select * from admin where admin_id between 100000 and 100010 order by admin_id
14.不用使用count(id),使用count(*)
15.不要做无谓的排序,应该使用索引进行排序
16.不要使用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
17.使用JOIN 时候,应该用小的结果驱动大的结果(left join 左边表结果尽量小如果有条件应该放到左边先处理,right join 同理反向),同事尽量把牵涉到多表联合的查询拆分多个query(多个连表查询效率低,容易到之后锁表和阻塞)
原来语句 select * from admin left join log on admin.admin_id = log.admin_id where log.admin_id>10
优化为: select * from (select * from admin where admin_id>10) T1 left join log on T1.admin_id = log.admin_id