首先创建几个结构复杂的表,导入10万条以上的数据进行测试。
1.SQL语句的优化
原则 1:尽量避免在列上进行运算,这样会导致索引失效。
例如原SQL语句为:
SELECT * FROM c WHERE YEAR (d)
> = 2011;
优化为:
SELECT * FROM c > = '2011-01-01';
原则 2:使用JOIN时,应该用小结果集驱动大结果集。同时把复杂的JOIN查询拆分成多个Query。因为JOIN多个表时,可能导致更多的锁定和堵塞。例如:
SELECT * FROM a JOIN b ON a.id = b.id
LEFT JOIN c ON c.time = a.date
……
原则 3:注意LIKE模糊查询的使用,避免%%。例如:
SELECT * FROM a WHERE name LIKE '%de%'
优化为:
SELECT * FROM a WHERE name > = 'de' AND name < 'df'
原则 4: 仅列出需要查询的字段,这对速度不会有明显影响,主要考虑节省内存。例如:
SELECT * FROM student;
优化为:
SELECT id,name,pwd FROM student;
原则 5: 使用批量插入语句节省交互。例如:
INSERT INTO aa (id,name) VALUES(1,'a');
INSERT INTO aa (id,name) VALUES(2,'b');
INSERT INTO aa (id,name) VALUES(3,'c');
优化为:
INSERT INTO aa (id,name) VALUES(1,'a'),(2,'b'),(3,'c');
原则 6: limit的基数比较大时使用between。例如:
SELECT * FROM article as article ORDER BY id LIMIT 1000000,10;
优化为:
SELECT * FROM article as article WHERE id BETWEEN 1000000 AND 1000010 ORDER BY id;
BETWEEN限定比LIMIT快,所以在海量数据访问时,建议用BETWEEN或是WHERE替换掉LIMIT。但是BETWEEN也有缺陷,如果id中间有断行或是中间部分id不读取的情况,总读取的数量会少于预计数量!
在取比较后面的数据时,通过desc方式把数据反向查找,以减少前端数据的扫描,让LIMIT的基数越小越好!
原则 7: 不要使用rand函数获取多条随机记录。例如:
SELECT * FROM table ORDER BY rand() LIMIT 20;
改为:
先用PHP产生随机数,把这个字符串传给MySQL,MySQL里用in查询。
原则 8: 避免使用NULL。
原则 9; 不要使用count(id),而应该是count(*)。
原则 10: 不要做无谓的排序操作,而应尽可能在索引中完成排序