MySql技巧個人筆記
1.數據null時sum的用法
mysql數據庫SUM(A+B)不一定等於SUM(A)+SUM(B),當A或B為NULL時,SUM(A+B)=NULL。
2.or改為in
同一字段,將or改寫為in()。OR效率:O(n);IN效率:O(Log n);當n很大時,OR會慢很多。注意控制in的個數,建議n小於200。
3. or和union的效率
(1)不同字段,將or改為union。
(2)相同字段(針對單表操作)
對於索引列來最好使用union all,因復雜的查詢【包含運算等】將使or、in放棄索引而全表掃描,除非你能確定or、in會使用索引。對於只有非索引字段來說你就老老實實的用or 或者in,因為 非索引字段本來要全表掃描而union all 只成倍增加表掃描的次數。對於及有索引字段【索引字段有效】又包含非索引字段來時,按理你也使用or 、in或者union all 都可以,但是我推薦使用or、in。
4.union all與union
若無需對結果進行去重,則用union all 而非union;union會自動對結果去重,有去重開銷。
5.Group by去除排序
Gourp by 實現分組、自動排序。則無需排序:order by null。
6.將字符轉換為數字
數字型VS字符串型索引:數字型更高效、查詢更快、占用空間更小。
7.拒絕大SQL
拒絕大sql,拆解成多條簡單sql:
(1)可能一條大sql就把整個數據庫堵死;
(2)簡單sql緩存命中率更高;
(3)減少鎖表時間,特別是MyISAM;
(4)用上多cpu,一條sql只能在一個cpu中運行。
8. Load data導數據
批量數據塊導入:
(1)成批裝載比單行裝載更快,不需要每次都刷新緩存;
(2)無索引裝載比索引裝載更快;
(3)Insert values,values,values減少索引刷新;
(4)Load data 比Insert快約20倍
盡量不要用insert….select….
(1) 延遲
(2)同步出錯
9.打散大批量更新
(1)大批量更新凌晨操作,避開高峰
(2)凌晨不限制
(3)白天上限默認為100條/秒(特殊再議)
10. mysql int(3)與int(11)的區別
總結,int(M) zerofill,加上zerofill後M才表現出有點點效果,比如 int(3) zerofill,你插入到數據庫裡的是10,則實際插入為010,也就是在前面補充加了一個0.如果int(3)和int(10)不加zerofill,則它們沒有什麼區別.M不是用來限制int個數的.
注意:這裡的M代表的並不是存儲在數據庫中的具體的長度,以前總是會誤以為int(3)只能存儲3個長度的數字,int(11)就會存儲11個長度的數字,這是大錯特錯的。
其實當我們在選擇使用int的類型的時候,不論是int(3)還是int(11),它在數據庫裡面存儲的都是4個字節的長度,在使用int(3)的時候如果你輸入的是10,會默認給你存儲位010,也就是說這個3代表的是默認的一個長度,當你不足3位時,會幫你不全,當你超過3位時,就沒有任何的影響。
11.count(distinct field)是魔鬼
Count(distinct field)查詢效率極低,數據量大時甚至會爆出內存不足。優化技巧:使用臨時表概念,先把distinct的field 經過group by過濾後,再對其進行count計算。
優化前:
優化後:
12.mysql函數
(1)replace函數
Update tr_app_data set content = replace(content,'SGSN206','SGSN1') where app_data_cat='AlarmMonitor_Widget_195'
(2)concat函數
select concat(LAC,'_',CI) from `sheet1`
(3)IFNULL函數
IFNULL(expr1,expr2) ,如果expr1不是NULL,IFNULL()返回expr1,否則它返回expr2。IFNULL()返回一個數字或字符串值。
(4)IF函數
如果expr1是TRUE(expr1<>0且expr1<>NULL),那麼IF()返回expr2,否則它返回expr3。IF()返回一個數字或字符串值,取決於它被使用的上下文。
(5)CASE WHEN函數
Case具有兩種格式。簡單Case函數和Case搜索函數
--簡單Case函數 如果case有條件,when 只能是對條件值的羅列,不能再加條件,否則出錯
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
如果case 沒有條件,when 裡面可以加個條件判斷
--Case搜索函數
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
13.單表去重並保留id最小的一條
數據庫現在不支持這樣的操作(對一個表進行select等子操作後,然後對該表做delete或者updata這類的操作。so,可以用臨時表解決。如下:
DELETE FROM table_test WHERE id NOT IN (SELECT id FROM (SELECT MIN(id) AS id FROM table_test AS t GROUP BY uid) t1);