- 尽量避免在列上进行运算,这样会导致索引失效.
原句:SELECT * FROM t WHERE YEAR(d) >= 2011;
优化:SELECT * FROM t WHERE d >= '2011-01-01';
- 使用JOIN时,应该用小结果集驱动大结果集.同时把复杂的JOIN查询拆分为多个query.因为JOIN多个表时,可能导致更多的锁定和堵塞.
SELECT * FROM a JOIN b ON a.id=b.id LEFT JOIN c ON c.time=a.date LEFT JOIN d ON c.pid=d.aid LEFT JOIN e ON e.cid=a.did
- 注意LIKE模糊查询的使用,避免%%
原句:SELECT * FROM t WHERE name LIKE '%de%';
优化:SELECT * FROM t WHERE name >= 'de' AND name < 'df';
- 仅列出需要查询的字段,这对速度不会有明显营销,主要考虑节省内存.
原句:SELECT * FROM test;
优化:SELECT name FROM test;
- 使用批量插入语句节省交互.
原句:INSERT INTO t(id,name) values(1,'a');
INSERT INTO t(id,name) values(2,'b');
INSERT INTO t(id,name) values(3,'c');
优化:INSERT INTO t(id,name) values(1,'a'),(2,'b'),(3,'c');
- limit的基数比较大的时候使用between.
原句:SELECT * FROM article order by id limit 10000,10;
优化:SELECT * FROM article where id between 10000 and 10010 order by id;
- ps:between限定比limit快,所以在海量数据访问时,建议使用between或者是where替换掉limit.
- 但是between也有缺陷,如果id中间有断行或者是中间部分id不读取的情况,总读取的数量会少于预计数量!(在读取比较后面的数据时,使用desc方式把数据反向查找,以减少前段数据的扫描,让limit的基数越小越好)
- 不要使用rand函数获取多条随机记录.
原句:select * from table order by rand() limit 20;
优化:select * from table as a join (select round(rand() * ((select MAX(id) from table) - (select min(id) from table)) + (select min(id) from table )) as id ) as b where a.id>b.id order by a.id limit 1;
当然也可以使用PHP产生随机数传给MySQL - 避免使用NULL.
- 不要使用count(id),而应该是count(*)
- 不要做无谓的排序操作,而应尽可能在索引中完成排序.
本文出自于《PHP核心技术与最佳实践》