MySQL使用小坑總結(一)
1、資料庫中的欄位型別不要使用long型,否則會造成查詢緩慢,可以選擇BigInt型別來代替。
2、避免select *。
3、如果表結構中欄位定義的型別與應用傳入的型別不一致,這時候可能會發生隱式轉換;兩個表join的時候,如果字符集定義不一致,也會導致隱式轉換,mysql中定義的隱式轉換規則如下所示:
a、兩個引數至少有一個是NULL時,比較的結果也是NULL,例外是使用<=>對兩個NULL做比較時會返回1,這兩種情況都不需要做型別轉換;
b、兩個引數都是字串,會按照字串來比較,不做型別轉換;
c、兩個引數都是整數,按照整數來比較,不做型別轉換;
d、十六進位制的值和非數字做比較死活,會被當作二進位制串;
e、有一個引數是TIMESTAMP或DATETIME,並且另外一個引數是常量,常量會被轉換為timestamp;
f、有一個引數是decimal型別,如果另外一個引數是decimal或者整數,會將整數轉換為decimal後進行比較,如果另外一個引數是浮點數,則會把decimal轉換為浮點數進行比較;
g、所有其它情況下,兩個引數都會被轉換為浮點數再進行比較;
隱式轉換會使索引失效,導致查詢無法命中索引。
4、limit m,n
mysql翻頁查詢使用下面的語法:select * from table limit m,n;
其中m是指記錄開始的index,資料庫中的第一條記錄標記為0,n是指從第m+1條記錄開始,取n條資料。
比如select * from table limit 2,4,該語句取出第3條至第6條資料,共4條記錄。
需要注意的是普通的limit M,N的翻頁寫法,在越往後翻頁的過程中速度越慢,原因是由於mysql會讀取表中的前M+N條資料,M越大,則效能越差。可以選擇的優化方式是使用關聯子查詢進行優化,如下面的實驗,我們先後用上下兩條語句查詢資料庫的100條資料:
優化前:select * from table limit 10000,100; 優化後:select * from hregiondb a,(select id from hregiondb limit 10000,100) b where a.id=b.id
兩條查詢語句的耗時如下圖,可見優化後查詢的速度快了不少。
5、刪除表中資料
如果要清空表中的所有記錄,可以使用如下兩種方式:
方式一:delete from table
方式二:truncate table
其中delete的方式可以返回被刪除的記錄數,但執行速度不快,相反,truncate不能返回被刪除的記錄條數,但是執行速度快。
推薦使用truncate方式,這是因為binlog有個row格式,delete時會把所有被操作資料的整行都記錄在binlog裡,如果表中資料量很大,會造成binlog的急劇膨脹。
此外採用先truncate後drop的方式也可以減少系統表被鎖定的時間。
7、索引要仔細設計,保證索引有很好的過濾性,這是因為索引本身也佔消耗。什麼叫過濾性好的索引,舉個例子,比如一張職工表,那麼性別欄位就無需建立索引。
8、optimize table
mysql中刪除了資料時,被刪除資料佔用的磁碟空間並沒有馬上被釋放,而是被寫入了一個標記為,只有執行了optimize之後,這部分空間包括索引位才會被釋放出來。
9、可以使用explain命令檢視sql語句的執行計劃
我們使用上面那條語句來看看explain命令的結果。
explain select * from hregiondb a,(select id from hregiondb limit 10000,100) b where a.id=b.id
結果截圖如下:
各個列的解釋簡列如下:
1、select_type,select型別,simple表示最簡單的select,primary出現在有子查詢的語句中,最外面的select查詢就是primary;
2、table,顯示這一行的資料是關於哪張表的;
3、type,顯示連線使用了何種型別,從最好到最差的連線型別為const、eq_reg、ref、range、indexhe和ALL;
4、possible_keys,顯示可能應用在該表中的索引;
5、key,實際使用的索引;
6、key_len,使用的索引的長度,該值越小越好;
7、ref,顯示索引的哪一列被使用了;
8、rows,mysql認為必須檢查的用來返回請求資料的行數;
9、Extra,額外資訊,如果是Using temporary或者Using filesort,意味著mysql不會使用索引,這樣的檢索會很慢;