Mysql SQL優化方法
1.單庫表別太多,一般保持在200以下為宜.
2.儘量避免SQL中出現運算,例如select a+5 from A
,讓DB功能單一化
3.表設計儘量小而精,能用5個欄位就不要用6個(除非業務上使用增加冗餘欄位來提升效能)。
4.SQL事務不能設計太大,比如一次性提交10W條insert
,當然這個不僅僅是效能問題了,可能直接記憶體溢位了。
一般來說insert
事務的話,5K-1W來做批處理就可以了(欄位不能太大)
5.設計表的時候儘量用”小資料型別”,比如儘量避免text
,blob
等這些大傢伙,優先使用ENUM和SET(小而美,範圍有限,百益無一害)
6.設計表字段能用數字型別就千萬別用字元型別,比如存IP地址,用int
varchar
(方法自己百度一下吧)。
7.儘量避免null
欄位,定義時儘量使用 not null
。原因是允許null
時不方便查詢優化,複合索引也會失效,而且如果列有索引時會額外佔用空間: a int(10) NOT NULL DEFAULT 0
8.圖片等大傢伙不要存DB,用FastDFS
等中介軟體或者直接使用七牛等雲端儲存。
9.大SQL儘量拆分,多核CPU每個CPU只能執行一個SQL,所以併發時,一堆小的可能效率更高一些,並且容易命中快取,而且不容易長時間鎖表(無論什麼鎖都是時間越短越好),當然這個要結合實際情況分析了,一大堆小的萬一增加IO負擔呢。
10.事務儘可能的小,程式碼別偷懶,全加到一個transaction
transaction
。
11.儲存過程,觸發器之類的能避就全避免了吧,維護不方便,人員變動時,很多時候就忘了,時間一長全是定時炸彈。
12.禁止select *
需要啥就取啥。
13.update
時,where
語句儘量要走索引,不然會全表掃描,一般情況下,1G的資料至少10S(想想這可是update啊,鎖住10S意味著啥)。
14.or
儘量不用,改為in()
,當然in
的範圍太多也不行,儘量別超100。
15.還是or
,如果:select a from A where b=1 or c=1
這種where
裡面不同欄位進行or
,這種儘量改為union
。
select a from A where b=1
union
select a from A where c=1
16.避免 “% 字首”
模糊查詢 。因為會導致索引失效,大資料量下是災難。
17.分頁時:Select a from A limit 10000,10;
這種大偏移量下效率非常低。可以考慮如下幾個方案:
select a from A WHERE id>=xxxx limit 11;
(將上一頁的最大值通過where id> 進行預處理,然後分頁)
select a from A WHERE id >= ( select a from A limit 10000,1 ) limit 10;
select a from A inner join (select a from A limit 10000,10) using (id) ;
18.避免使用count(*)
,不知道為什麼mysql優化這麼個東西有那麼難麼,但是實際上大數量下這個東西真心慢,1000W以上至少幾秒,作為替代方案,考慮使用nosql
例如redis
,memcached
存下來,但是要定時校對。
還有一個辦法,直接做一個表存下來,每次增加或者減少都在這個表做update
增減。
19.UNION ALL
而非 UNION
,看需要啦,一般不用去重的業務的話去重壓力不小,能省則省。
20.儘量不用 INSERT SELECT
,資料量大有延遲,同步完了可能有錯誤。