看到社區裏面你們很是踊躍的討論關於MySQL優化,特別是Order by優化的問題[via],我就將本身在平時項目中積累的一些經驗和你們分享一下。一家之言,未免有誤,歡迎拍磚,僅供參考。 關於創建索引的幾個準則: 一、合理的創建索引可以加速數據讀取效率,不合理的創建索引反而會拖慢數據庫的響應速度。 二、索引越多,更新數據的速度越慢。 三、儘可能在採用MyIsam做爲引擎的時候使用索引(由於MySQL以BTree存儲索引),而不是InnoDB。但MyISAM不支持Transcation。 四、當你的程序和數據庫結構/SQL語句已經優化到沒法優化的程度,而程序瓶頸並不能順利解決,那就是應該考慮使用諸如memcached這樣的分佈式緩存系統的時候了。 五、習慣和強迫本身用EXPLAIN來分析你SQL語句的性能。 一個很容易犯的錯誤: 不要在選擇的欄位上放置索引,這是無心義的。應該在條件選擇的語句上合理的放置索引,好比where,order by。 例子: SELECT id,title,content,cat_id FROM article WHERE cat_id = 1;html 上面這個語句,你在id/title/content上放置索引是毫無心義的,對這個語句沒有任何優化做用。可是若是你在外鍵cat_id上放置一個索引,那做用就至關大了。 幾個經常使用ORDER BY語句的MySQL優化: 一、ORDER BY + LIMIT組合的索引優化。若是一個SQL語句形如: SELECT [column1],[column2],.... FROM [TABLE] ORDER BY [sort] LIMIT [offset],[LIMIT];數據庫 這個SQL語句優化比較簡單,在[sort]這個欄位上創建索引便可。 二、WHERE + ORDER BY + LIMIT組合的索引優化,形如:
SELECT [column1],[column2],.... FROM [TABLE] WHERE [columnX] = [VALUE] ORDER BY [sort] LIMIT[offset],[LIMIT];緩存 這個語句,若是你仍然採用第一個例子中創建索引的方法,雖然能夠用到索引,可是效率不高。更高效的方法是創建一個聯合索引(columnX,sort) 三、WHERE + IN + ORDER BY + LIMIT組合的索引優化,形如:
SELECT [column1],[column2],.... FROM [TABLE] WHERE [columnX] IN ([value1],[value2],...) ORDER BY[sort] LIMIT [offset],[LIMIT];分佈式 這個語句若是你採用第二個例子中創建索引的方法,會得不到預期的效果(僅在[sort]上是using index,WHERE那裏是using where;using filesort),理由是這裏對應columnX的值對應多個。 這個語句怎麼優化呢?我暫時沒有想到什麼好的辦法,因而就用了一個愚蠢的辦法,那就是將這個語句用UNION分拆,而後創建第二個例子中的索引:
SELECT [column1],[column2],.... FROM [TABLE] WHERE [columnX]=[value1] ORDER BY [sort] LIMIT[offset],[LIMIT] |