MySQL數(shù)據(jù)庫查詢優(yōu)化
上兩周一直想辦法提高查詢速度,取得一點(diǎn)效果,解決了部分問題,記下來以便將來自己查看。
由于公司沒有專門的DBA,我自己對(duì)mysql數(shù)據(jù)庫也不是很熟悉,而且這個(gè)JAVA開發(fā)的網(wǎng)絡(luò)審計(jì)系統(tǒng)的管理系統(tǒng),是經(jīng)過了N多人幾年時(shí)間的修修改改,今天到我們手里,要改成能支持大流量情況的版本,所以對(duì)我們這個(gè)只有幾個(gè)人的JAVA組來說,確實(shí)是個(gè)難題。
這個(gè)大流量的情況在以前的文章里也提到過,就是要支持每秒鐘處理1G左右的網(wǎng)絡(luò)數(shù)據(jù)包,HTTP協(xié)議的數(shù)據(jù)包最多,因此HTTP協(xié)議分析模塊的流水日志表記錄***,據(jù)估算可能到達(dá)一天4000萬條記錄,采用一天一張表,那也是很大的,我看了.MYD文件大小,已經(jīng)是8G多了。
而我們管理系統(tǒng)查詢?nèi)罩居涗洉r(shí),對(duì)好幾個(gè)字段都要進(jìn)行條件查詢,而且有幾個(gè)字段長度達(dá)到256,在8G這么大的表里查詢一個(gè)字符串,如果找不到,那必定從頭要查到尾,速度慢得根本受不了。客戶還要好幾個(gè)字段一起設(shè)置條件來查詢,這樣基本上是二三十分鐘都出不來,系統(tǒng)可用性極差。
我采用的方法是以測(cè)試為主,同時(shí)看JAVA代碼,通過Log4j和Perf4j日志,看每個(gè)sql語句使用的時(shí)間,尋找性能瓶頸,然后有的放矢地進(jìn)行優(yōu)化。
對(duì)查詢最有效果的優(yōu)化,自然是建立索引了,ID自然是自增、主鍵,這個(gè)前人已經(jīng)做了;從where語句分析,時(shí)間字段作為查詢條件很多,時(shí)間是8字節(jié),而且不重復(fù),設(shè)置索引比較適合。我把時(shí)間設(shè)置為索引,有一點(diǎn)效果,但不大,估算一下:8 * 4000 0000 = 320 000 000 字節(jié),4000萬記錄的表僅僅時(shí)間一個(gè)字段的索引將是320M,這還僅僅是我們上百張表的一張表而已(客戶要求我們至少保存3個(gè)月記錄)。
建立索引能起到一定作用,但還是解決不了我們的問題。物理表建立不能再縮短時(shí)間了,因?yàn)橐惶煲粡埍恚?個(gè)月就91~92張表,30個(gè)協(xié)議模塊就得2700多,這僅僅是協(xié)議流水日志表,還有其它表呢。
也不能把客戶要求做成條件的字段都設(shè)置成索引,那索引表將和原表差不多大,索引就失去意義了。在數(shù)據(jù)庫本身上優(yōu)化,想去想來實(shí)在一下子想不到好辦法,感覺數(shù)據(jù)量大了,就算在Oracle上也沒有什么神奇辦法吧。
我***采用分段查詢的方法,就是4000萬條數(shù)據(jù),我不管你設(shè)置什么條件來查詢,我都是平均劃為成N段來查詢,比如400萬為一段,在頁面上提供一個(gè)下拉單:0~400萬,400~800萬,…,3600~4000萬,雖然查詢比較麻煩一點(diǎn),但每段查詢的速度大大提高,控制在30秒左右,犧牲一些可用性,總比30分鐘還查不出來好吧。
流水日志可以采用分段查詢解決,但客戶要求的各種統(tǒng)計(jì)呢,這不能說分段統(tǒng)計(jì),別人要統(tǒng)計(jì)2天的,你分開是不行的。
以前已經(jīng)采用了一次預(yù)統(tǒng)計(jì),預(yù)先定時(shí)在后臺(tái)對(duì)流水日志表進(jìn)行統(tǒng)計(jì)一次,保存到預(yù)統(tǒng)計(jì)表,等用戶來查詢時(shí),從預(yù)統(tǒng)計(jì)表進(jìn)行各種查詢—-這個(gè)做法好,不得不夸下前任開發(fā)人員。
但現(xiàn)在形勢(shì)不同了,因?yàn)轭A(yù)統(tǒng)計(jì)表是采用一個(gè)月一張的,就現(xiàn)在流水日志表的規(guī)模,那預(yù)統(tǒng)計(jì)表可能一張表超過4000萬,具體看客戶網(wǎng)絡(luò)數(shù)據(jù)的分布情況,不好估計(jì)。
***我和同事們對(duì)統(tǒng)計(jì)模式詳細(xì)分析,一個(gè)同事提出再在預(yù)統(tǒng)計(jì)表基礎(chǔ)上進(jìn)行二次預(yù)統(tǒng)計(jì),我們估算了一下,基本上等用戶來查詢時(shí),所面對(duì)的表已經(jīng)很小了,最多幾千條記錄,很快了。
解決統(tǒng)計(jì)查詢過程中,讓我體會(huì)到詳細(xì)分析業(yè)務(wù)流程細(xì)節(jié),作出相應(yīng)的優(yōu)化,有時(shí)是可以解決問題的。
總體上來說,對(duì)數(shù)據(jù)庫查詢的優(yōu)化,我們采取了一些常規(guī)的優(yōu)化之后,如果還沒有取得想要的效果,我們有時(shí)候不必硬碰硬去優(yōu)化查詢本身,改變一下使用模式,找找業(yè)務(wù)處理流程是否還有可修改的,說不定就輕松解決了存在的難題。
還有就是主管要把整個(gè)開發(fā)組積極性調(diào)動(dòng)起來,大家一起測(cè)試、分析、想辦法、驗(yàn)證,***一致確定一個(gè)可行的方案,然后大家分頭去不打折扣的實(shí)現(xiàn)。
原文鏈接:http://www.cppblog.com/cool-liangbing/archive/2009/06/14/87665.html