mysql 優(yōu)化注意事項(xiàng)

優(yōu)化要注意的一些事(重點(diǎn))

1. 索引其實(shí)就是一種歸類方式徒蟆,當(dāng)某一個字段屬性都不能歸類,建立索引后是沒什么效果的型型,或歸類就二種(0和1)段审,且各自都數(shù)據(jù)對半分,建立索引后的效果也不怎么強(qiáng)闹蒜。

2. 主鍵的索引是不一樣的寺枉,要區(qū)別理解。

3. 當(dāng)時間存儲為時間戳保存的可以建立前綴索引绷落。

4. 在什么是字段上建立索引姥闪,需要根據(jù)查詢條件而定,不要一上來就建立索引砌烁,浪費(fèi)內(nèi)存還有可能用不到筐喳。

5. 大字段(blob)不要建立索引,查詢也不會走索引。

6. 常用建立索引的地方:

1)主鍵的聚集索引

2)外鍵索引

3)類別只有0和1就不要建索引了避归,沒有意義荣月,對性能沒有提升,還影響寫入性能

4)用模糊其實(shí)是可以走前綴索引

7. 唯一索引一定要小心使用槐脏,它帶有唯一約束喉童,由于前期需求不明等情況下,可能造成我們對于唯一列的誤判顿天。

8. 由于我們建立索引并想讓索引能達(dá)到最高性能堂氯,這個時候我們應(yīng)當(dāng)充分考慮該列是否適合建立索引,可以根據(jù)列的區(qū)分度來判斷牌废,區(qū)分度太低的情況下可以不考慮建立索引咽白,區(qū)分度越高效率越高。

SELECTCOUNT(DISTINCT 列_xx)/COUNT(*)FROM 表

9. 寫入比較頻繁的時候鸟缕,不能開啟MySQL的查詢緩存晶框,因?yàn)樵诿恳淮螌懭氲臅r候不光要寫入磁盤還的更新緩存中的數(shù)據(jù)。

10. 建索引的目的:

1)加快查詢速度懂从,使用索引后查詢有跡可循授段。

2)減少I/O操作,通過索引的路徑來檢索數(shù)據(jù)番甩,不是在磁盤中隨機(jī)檢索侵贵。

3)消除磁盤排序,索引是排序的缘薛,走完索引就排序完成窍育。

11. 其實(shí)建索引的原理就是將磁盤I/O操作的最小化,不在磁盤中排序宴胧,而是在內(nèi)存中排好序漱抓,通過排序的規(guī)則去指定磁盤讀取就行,也不需要在磁盤上隨機(jī)讀取恕齐。

12. 由于磁盤整理磁盤碎片乞娄,所有有的時候我們也可以通過建立聚集索引來減少這一類的問題。

13. 當(dāng)一個表中有100萬數(shù)據(jù)显歧,而經(jīng)常用到的數(shù)據(jù)只有40萬或40萬以下仪或,是不用考慮建立索引的,沒什么性能提升追迟。

14. 什么時候不適合建立索引:

1)頻繁更新的字段不適合建立索引

2)where條件中用不到的字段不適合建立索引,都用不到建立索引沒有意義還浪費(fèi)空間

3)表數(shù)據(jù)可以確定比較少的不需要建索引

4)數(shù)據(jù)重復(fù)且發(fā)布比較均勻的的字段不適合建索引(唯一性太差的字段不適合建立索引)骚腥,例如性別敦间,真假值

5)參與列計(jì)算的列不適合建索引,如:

select*fromtable where amount+100>1000,--這樣是不走索引的廓块,可以改造為:select*fromtable where amount>1000-100厢绝。

15. 使用count統(tǒng)計(jì)數(shù)據(jù)量的時候建議使用count(*)而不是count(列),因?yàn)閏ount(*)MySQL是做了優(yōu)化的带猴。

16. 二次SQL查詢區(qū)別不大的時候昔汉,不能按照二次執(zhí)行的時間來判斷優(yōu)化結(jié)果,沒準(zhǔn)第一次查詢后又保存緩存數(shù)據(jù)拴清,導(dǎo)致第二次查詢速度比第二次快靶病,很多時候我們看到的都是假象。

17. 什么時候開MySQL的查詢緩存口予,交易系統(tǒng)(寫多娄周、讀少)、SQL優(yōu)化測試沪停,建議關(guān)閉查詢緩存煤辨,論壇文章類系統(tǒng)(寫少、讀多)木张,建議開啟查詢緩存众辨。

18. Explain 執(zhí)行計(jì)劃只能解釋SELECT操作。

19. 查詢優(yōu)化可以考慮讓查詢走索引舷礼,走索引能提升查詢速度鹃彻,索引覆蓋是最快的,如下就是讓分頁走覆蓋索引提高查詢速度且轨。

Select*fromfentrust eInnerjoin(select fidfromfentrust limit4100000,10)a on a.fid=e.fid

20. 子查詢比join快浮声,雖然規(guī)律不絕對,但對大表多數(shù)有效

21. 復(fù)雜SQL語句優(yōu)化的思路:

1)首先考慮在一個表中能不能取到有關(guān)的信息旋奢,盡量少關(guān)聯(lián)表

2)關(guān)聯(lián)條件爭取都走主鍵或外鍵查詢條件泳挥,能走到對應(yīng)的索引

3)爭取在滿足業(yè)務(wù)上走小集合數(shù)據(jù)查找

4)INNER JOIN 和子查詢哪個更快,場景不一致速度也不同

22. where條件多條件一定要按照小結(jié)果集排大結(jié)果集前面

23. 盡量避免大事務(wù)操作至朗,提高系統(tǒng)并發(fā)能力屉符,有時無法避免,改用定時器延遲處理锹引。

24. 什么情況不走索引:

SELECT` famount `FROM` fentrust `WHERE` famount `+10=30;--不會使用索引,因?yàn)樗兴饕袇⑴c了計(jì)算 SELECT`famount`FROM`fentrust`WHERELEFT(`fcreateTime`,4)<1990;--不會使用索引,因?yàn)槭褂昧撕瘮?shù)運(yùn)算,原理與上面相同 SELECT*FROM` fuser`WHERE`floginname`LIKE‘138%'--走索引 SELECT*FROM` fuser `WHERE` floginname `LIKE"%7488%"--不走索引--正則表達(dá)式不使用索引,這應(yīng)該很好理解,所以為什么在SQL中很難看到regexp關(guān)鍵字的原因--字符串與數(shù)字比較不使用索引;EXPLAIN SELECT*FROM`a`WHERE`a`=1--不走索引 select*fromfuser where floginname='xxx'or femail='xx'or fstatus=1--如果條件中有or,即使其中有條件帶索引也不會使用矗钟。換言之,就是要求使用的所有字段,都必須建立索引,我們建議大家盡量避免使用or 關(guān)鍵字

25. 如果MySQL估計(jì)使用全表掃描要比使用索引快,則不使用索引嫌变。

26. 使用UNION ALL 替換OR多條件查詢并集吨艇。

27. 在大數(shù)據(jù)表刪除也是一個問題,避免刪除過程數(shù)據(jù)庫奔潰腾啥,可以考慮分配刪除东涡,一次刪1000條冯吓,刪完后等一會繼續(xù)刪除

deletefromlogs where log_date<=’2012-11-01’ limit1000

28. 大數(shù)據(jù)表優(yōu)化:

1)建立匯總表

2)建立流水表

3)分庫分表

29. 建立匯總表,首先不用考慮分庫分表疮跑,使用定時器定時去匯總组贺。

30. 分表,可以按水平或垂直切分祖娘。垂直分表其實(shí)就是將經(jīng)常使用的數(shù)據(jù)和很少使用的數(shù)據(jù)進(jìn)行垂直的切分失尖,切分到不同的庫,提高單庫的數(shù)據(jù)容量渐苏,如:前3個月之前的交易記錄就可以放另一個庫中掀潮。

31. 建立流水表,數(shù)據(jù)冗余整以,有這個表記錄流水變更就不用去寫復(fù)雜SQL計(jì)算流水胧辽。

32. 分庫,多數(shù)據(jù)庫相同庫結(jié)構(gòu)公黑,分發(fā)處理并發(fā)能力邑商,但同時帶來了數(shù)據(jù)同步問題,也可以使用分庫做主備分離

32. SQL優(yōu)化順序:

1)盡量少作計(jì)算凡蚜。

2)盡量少 join人断。

3)盡量少排序。

4)盡量避免 select *朝蜘。

5)盡量用 join 代替子查詢恶迈。

6)盡量少 or。

7)盡量用 union all 代替 union谱醇。

8)盡量早過濾暇仲。

9)避免類型轉(zhuǎn)換。

10)優(yōu)先優(yōu)化高并發(fā)的 SQL副渴,而不是執(zhí)行頻率低某些“大”SQL奈附。

11)從全局出發(fā)優(yōu)化,而不是片面調(diào)整煮剧。

12)盡可能對每一條運(yùn)行在數(shù)據(jù)庫中的SQL進(jìn)行 Explain斥滤。

33. 如下是30條大數(shù)據(jù)表優(yōu)化要點(diǎn):

1)對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描勉盅,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引佑颇。

2)應(yīng)盡量避免在 where 子句中對字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描草娜,如:select id from t where num is null可以在num上設(shè)置默認(rèn)值0挑胸,確保表中num列沒有null值,然后這樣查詢:select id from t where num=0

3)應(yīng)盡量避免在 where 子句中使用!=或<>操作符宰闰,否則引擎將放棄使用索引而進(jìn)行全表掃描茬贵。

4)應(yīng)盡量避免在 where 子句中使用or 來連接條件凸克,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:select id from t where num=10 or num=20可以這樣查詢:select id from t where num=10 union all select id from t where num=20

5)in 和 not in 也要慎用闷沥,否則會導(dǎo)致全表掃描,如:select id from t where num in(1,2,3) 對于連續(xù)的數(shù)值咐容,能用 between 就不要用 in 了:select id from t where num between 1 and 3

6)下面的查詢也將導(dǎo)致全表掃描:select id from t where name like '李%'若要提高效率舆逃,可以考慮全文檢索。

7)如果在 where 子句中使用參數(shù)戳粒,也會導(dǎo)致全表掃描路狮。因?yàn)镾QL只有在運(yùn)行時才會解析局部變量,但優(yōu)化程序不能將訪問計(jì)劃的選擇推遲到運(yùn)行時蔚约;它必須在編譯時進(jìn)行選擇奄妨。然 而,如果在編譯時建立訪問計(jì)劃苹祟,變量的值還是未知的砸抛,因而無法作為索引選擇的輸入項(xiàng)。如下面語句將進(jìn)行全表掃描:select id from t where num=@num可以改為強(qiáng)制查詢使用索引:select id from t with(index(索引名)) where num=@num

8)應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作树枫,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描直焙。如:select id from t where num/2=100應(yīng)改為:select id from t where num=100*2

9)應(yīng)盡量避免在where子句中對字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描砂轻。如:select id from t where substring(name,1,3)='abc' 奔誓,name以abc開頭的id 應(yīng)改為: select id from t where name like 'abc%'

10)不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算搔涝,否則系統(tǒng)將可能無法正確使用索引厨喂。

11)在使用索引字段作為條件時,如果該索引是復(fù)合索引庄呈,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引蜕煌,否則該索引將不會被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致抒痒。

12)不要寫一些沒有意義的查詢幌绍,如需要生成一個空表結(jié)構(gòu):select col1,col2 into #t from t where 1=0 這類代碼不會返回任何結(jié)果集,但是會消耗系統(tǒng)資源的故响,應(yīng)改成這樣: create table #t(...)

13)很多時候用 exists 代替 in 是一個好的選擇:select num from a where num in(select num from b) 用下面的語句替換: select num from a where exists(select 1 from b where num=a.num)

14)并不是所有索引對查詢都有效傀广,SQL是根據(jù)表中數(shù)據(jù)來進(jìn)行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時彩届,SQL查詢可能不會去利用索引伪冰,如一表中有字段sex,male樟蠕、female幾乎各一半贮聂,那么即使在sex上建了索引也對查詢效率起不了作用靠柑。

15)索引并不是越多越好,索引固然可 以提高相應(yīng)的 select 的效率吓懈,但同時也降低了 insert 及 update 的效率歼冰,因?yàn)?insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮耻警,視具體情況而定隔嫡。一個表的索引數(shù)最好不要超過6個,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有 必要甘穿。

16)應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列腮恩,因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整温兼,會耗費(fèi)相當(dāng)大的資源秸滴。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為 clustered 索引募判。

17)盡量使用數(shù)字型字段荡含,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型,這會降低查詢和連接的性能届垫,并會增加存儲開銷内颗。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時會逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了敦腔。

18)盡可能的使用 varchar/nvarchar 代替 char/nchar 均澳,因?yàn)槭紫茸冮L字段存儲空間小,可以節(jié)省存儲空間符衔,其次對于查詢來說找前,在一個相對較小的字段內(nèi)搜索效率顯然要高些。

19)任何地方都不要使用 select * from t 判族,用具體的字段列表代替“*”躺盛,不要返回用不到的任何字段。

20)盡量使用表變量來代替臨時表形帮。如果表變量包含大量數(shù)據(jù)槽惫,請注意索引非常有限(只有主鍵索引)。

21)避免頻繁創(chuàng)建和刪除臨時表辩撑,以減少系統(tǒng)表資源的消耗界斜。

22)臨時表并不是不可使用,適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行Ш霞剑绺鬓保?dāng)需要重復(fù)引用大型表或常用表中的某個數(shù)據(jù)集時。但是君躺,對于一次性事件峭判,最好使用導(dǎo)出表开缎。

23)在新建臨時表時,如果一次性插入數(shù)據(jù)量很大林螃,那么可以使用 select into 代替 create table奕删,避免造成大量 log ,以提高速度疗认;如果數(shù)據(jù)量不大急侥,為了緩和系統(tǒng)表的資源,應(yīng)先create table侮邀,然后insert。

24)如果使用到了臨時表贝润,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除绊茧,先 truncate table ,然后 drop table 打掘,這樣可以避免系統(tǒng)表的較長時間鎖定华畏。

25)盡量避免使用游標(biāo),因?yàn)橛螛?biāo)的效率較差尊蚁,如果游標(biāo)操作的數(shù)據(jù)超過1萬行亡笑,那么就應(yīng)該考慮改寫。

26)使用基于游標(biāo)的方法或臨時表方法之前横朋,應(yīng)先尋找基于集的解決方案來解決問題仑乌,基于集的方法通常更有效。

27)與臨時表一樣琴锭,游標(biāo)并不是不可使 用晰甚。對小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數(shù)據(jù)時决帖。在結(jié)果集中包括“合計(jì)”的例程通常要比使用游標(biāo)執(zhí)行的速度快厕九。如果開發(fā)時 間允許,基于游標(biāo)的方法和基于集的方法都可以嘗試一下地回,看哪一種方法的效果更好扁远。

28)在所有的存儲過程和觸發(fā)器的開始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時設(shè)置 SET NOCOUNT OFF 刻像。無需在執(zhí)行存儲過程和觸發(fā)器的每個語句后向客戶端發(fā)送DONE_IN_PROC 消息畅买。

29)盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力细睡。

30)盡量避免向客戶端返回大數(shù)據(jù)量皮获,若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理纹冤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洒宝,一起剝皮案震驚了整個濱河市购公,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雁歌,老刑警劉巖宏浩,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異靠瞎,居然都是意外死亡比庄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門乏盐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來佳窑,“玉大人,你說我怎么就攤上這事父能∩翊眨” “怎么了?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵何吝,是天一觀的道長溉委。 經(jīng)常有香客問我,道長爱榕,這世上最難降的妖魔是什么瓣喊? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮黔酥,結(jié)果婚禮上藻三,老公的妹妹穿的比我還像新娘。我一直安慰自己跪者,他們只是感情好趴酣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坑夯,像睡著了一般岖寞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柜蜈,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天仗谆,我揣著相機(jī)與錄音,去河邊找鬼淑履。 笑死隶垮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秘噪。 我是一名探鬼主播狸吞,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹋偏?” 一聲冷哼從身側(cè)響起便斥,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎威始,沒想到半個月后枢纠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡黎棠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年晋渺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓斩。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡木西,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出随静,到底是詐尸還是另有隱情八千,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布挪挤,位于F島的核電站,受9級特大地震影響关翎,放射性物質(zhì)發(fā)生泄漏扛门。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一纵寝、第九天 我趴在偏房一處隱蔽的房頂上張望论寨。 院中可真熱鬧,春花似錦爽茴、人聲如沸葬凳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽火焰。三九已至,卻和暖如春胧沫,著一層夾襖步出監(jiān)牢的瞬間昌简,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工绒怨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纯赎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓南蹂,卻偏偏與公主長得像犬金,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容