首先創建幾個結構復雜的表,導入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: 不要做無謂的排序操作,而應盡可能在索引中完成排序