關於Mysql SQL優化的總結,持續更新中

SQL優化的思路:

1.優化更須要優化的sql;
2.定位優化對象的性能瓶頸:優化前需瞭解查詢的瓶頸是IO仍是CPU,可經過PROFILING很容易定位查詢的瓶頸。
3.明確優化目標;
4.從Explain入手;
5.多使用profile;算法

SQL優化的基本原則:

1.永遠用小結果集驅動大結果集;
From子句中sql解析順序爲從右向左,執行時會以最左邊的表爲基礎表循環與右邊表數據作笛卡爾積,因此以小結果集驅動能減小循環次數,從而減小對被驅動結果集的訪問,從而減小被驅動表的鎖定。
2.儘量在索引中完成排序;
排序算法有兩種:a.查出排序字段和行指針,排序,再經過行指針得到行數據所需列,返回結果集;b.取出全部排序列數據,在排序緩衝區中排完序直接返回結果集。
索引排序是利用索引的有序性對數據排序的。
3.只取出子集須要的colums
4.僅僅使用最有效的過濾條件;
5.儘量避免複雜的Join和子查詢;sql

索引的好處:

(1).提升數據檢索效率,下降數據庫的IO成本。
(2).下降數據排序成本:要求排序字段和索引鍵字段一致。
(3).下降數據分組成本:由於分組以前會先排序,贊成若是分組字段與索引字段一致,會下降分組消耗的成本。數據庫

索引的弊端:

(1).索引是獨立於基礎數據的數據庫對象,所以它會佔用存儲空間。
(2).數據新增、更新會致使索引的同步更新,因此會增長數據新增、更新所消耗的成本。數組

判斷是否須要建立索引:

(1).較爲頻繁的做爲查詢條件的字段須要建立索引
(2). 惟一性太差的字段不適合單首創建索引,即便頻繁做爲查詢條件;
(3).更新很是頻繁的字段不適合建立索引;
(4).不會出如今where子句中的字段不要建立索引;
一、只要能知足你的需求,應儘量使用更小的數據類型:例如使用MEDIUMINT代替INT 二、儘可能把全部的列設置爲NOT NULL,若是你要保存NULL,手動去設置它,而不是把它設爲默認值。 三、儘可能少用VARCHAR、TEXT、BLOB類型 四、若是你的數據只有你所知的少許的幾個。最好使用ENUM類型 五、正如graymice所講的那樣,創建索引。服務器

SQL編寫注意事項:

1.原則一、僅列出須要查詢的字段,這對速度不會明顯的影響,主要是考慮節省應用程序服務器的內存。
2.原則二、儘可能避免在列上作運算,這樣致使索引失效。
3.原則三、使用JOIN 時候,應該用小的結果驅動大的結果(left join 左邊表結果儘可能小 若是有條件應該放到左邊先處理,right join 同理反向),同事儘可能把牽涉到多表聯合的查詢拆分多個query(多個連表查詢效率低,容易到以後鎖表和阻塞)。
4.原則四、注意LIKE 模糊查詢的使用, 避免使用 %% ,可使用 後面帶% ,雙%是不走索引的。
5.原則五、使用批量插入節省交互 (當如若是使用存儲過程來處理批量的sql 各類邏輯是更好的選擇)。
6.原則六、limit的基數比較大時使用between。函數

原來語句:select * from admin order by admin_id limit 100000,10
優化爲:  select * from admin where admin_id between 100000 admin 100010 order by admin_id

7.原則七、不要使用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

8.原則八、避免使用NULL。
9.原則9. 不要使用 count(id) 使用 count(*)。
10.原則十、不要作無謂的排序操做,而應該使用索引列完成排序。即order排序列必爲索引
11.原則十一、where條件中,過濾量最大的條件放在where子句最後;
12.原則十二、在索引列上使用計算、改變索引列的類型(不匹配的數據類型)、在索引列上使用!=將放棄索引;
13.運算符效率:exists高於in高於or,(not exists高於not in); IN、OR子句常會使用工做表,使索引失效。若是不產生大量重複值,能夠考慮把子句拆開。拆開的子句中應該包含索引。用union 鏈接
14.避免在索引列上使用is null和is not null;
15.用union-all替代union; 16.採用as 別名 採用綁定變量有助於提升效率;
17.使用函數=將放棄索引;
18/避免使用HAVING字句優化

B-tree 索引和 hash索引

Innodb和MyISAM默認的索引是Btree索引;而Mermory默認的索引是Hash索引。指針

hash索引
所謂Hash索引,當咱們要給某張表某列增長索引時,將這張表的這一列進行哈希算法計算,獲得哈希值,排序在哈希數組上。因此Hash索引能夠一次定位,其效率很高,而Btree索引須要通過屢次的磁盤IO,可是innodb和myisam之因此沒有采用它,是由於它存在着好多缺點:
一、由於Hash索引比較的是通過Hash計算的值,因此只能進行等式比較,不能用於範圍查詢
一、每次都要全表掃描
二、因爲哈希值是按照順序排列的,可是哈希值映射的真正數據在哈希表中就不必定按照順序排列,因此沒法利用Hash索引來加速任何排序操做
三、不能用部分索引鍵來搜索,由於組合索引在計算哈希值的時候是一塊兒計算的。
四、當哈希值大量重複且數據量很是大時,其檢索效率並無Btree索引高的。code

Btree索引(單獨文章描述) 至於Btree索引,它是以B+樹爲存儲結構實現的。 可是Btree索引的存儲結構在Innodb和MyISAM中有很大區別。 因此咱們常常會說MyISAM中數據文件和索引文件是分開的。 所以MyISAM的索引方式也稱爲非彙集,Innodb的索引方式成爲彙集索引。 至於輔助索引,相似於主索引,惟一區別就是主索引上的值不能重複,而輔助索引能夠重複。

相關文章
相關標籤/搜索