1. 程式人生 > >淺談索引對資料庫效能的影響

淺談索引對資料庫效能的影響

大家都知道,對於資料庫來說,常見的瓶頸問題多是CPU or IO過高造成的,如果能夠有效的解決這兩個問題,那麼的確是功德可見的,那麼業界現在也有很多的方式在達到這樣的目的,比如:在DB層的前面加一箇中間層:例如:memcached。做DB的資料快取,然後從一定程度上減少熱點資料訪問的磁碟IO(這裡我們暫時不去考慮FIFO,LRU,LFO的對資料的影響)、也有將資料進行分庫分表儲存這些技術。今天我個人淺談下另外一個方面,索引。因為在我個人看來,對於資料庫的調優(非專業DBA,錯誤,遺漏之處,請指點)主要有以下幾點:

1、整體架構設計:對於db層的考慮(比如;上面說到的memcached、分庫分表設定等技術架構的設計)

2、sql語句的優化(後續詳述。比如:in、not in、group by等)

3、db表的設計(例如:儘量用not null,不要create 表的時候enable null、欄位的型別選擇,例如:varchar,char,int,enum等的選擇原則)

4、儲存引擎(例如mysql的myisam和innodb的儲存引擎,在什麼時候該用啥引擎)的選擇、預設charset的選擇。例如:mysql的latin1還是那個啥?right,UTF8.......

5、索引的使用。

OK,暫時就想到這麼多。今天淺淺的談下,索引這個“大神”

   當我們exec一條sql語句的時候,explain:sql instance:結果發現在key和extra分別為null、filesort的時候是不是就會有衝動要加索引?會?不會?恩,不會,理性。還要看下這個sql的響應時間和操作的資料量級別大小,如果資料量大,又是all scan,那的確是需要考慮下是否應加入索引啦。那麼索引,索引,是不是就是簡單的一個create index index_name on table_name(fields_name)就OK了呢?

   記得以前在某裡面試的時候曾經提到過這個問題,那麼我個人覺得,索引的確能在某些情況下幫助我們去解決一些db層的效能問題,但是並不是說它就是萬能的。為什麼呢?

 1、建立索引,我們是否要考慮下,該在哪個欄位上建立索引(比如:是where後面的常用欄位還是非)

2、OK,那就在where後面常用的欄位上建嘛!~(那麼,加一句:如果這個欄位在where後面被函式操作了呢?)

3、OK,where後面常用欄位,並且不參與函式的運算建!~(ok,那麼,我該對它建什麼型別的索引呢?聚集?非聚集?)

......所以我個人對於是否該建索引的問題,應該要關注以下幾個問題:

1、建索引的位置。對於經常使用作為條件的欄位建立索引

2、建立索引之前,檢視建立之後,是否會因為本身sql語句的問題,造成索引失效

例如:select...from A where to_days(current_date)-to_days(date_col)<=10

查詢date_col值離current_date十天內的資料,但是建立在date_col上的索引會失效,因為它參與了函式的運算。對吧,喵~如何修改呢?

select...from a where date_col>=date_sub(current_date,interval 10 day);這樣,你建立在date_col上的索引是生效的。但是其實還是可以進一步改進,為啥呢?因為current_date會阻止查詢快取把結果快取,此處可以用常量代替掉current_date.(對查詢快取有興趣進一步瞭解的,請google下呵呵)~

3、在對索引所建的位置確定並對該欄位(已建索引)參與的sql語句分析之後,那麼對於索引該建立什麼型別也需要分析下。眾所周知,對於該列如果說重複的值很多,那麼一般都推薦建點陣圖索引,對於日期儲存的欄位,一般建議建立函式索引,對於不重複的欄位,一般推薦聚集索引。(這裡談到聚集索引,其實在mysql裡面還要跟儲存引擎有點牽連,因為innodb本身來說,使用innodb的情況下,儲存引擎預設使用的索引是B-TREE索引,B-TREE索引對於寫多讀少的業務是比較好的,否則,效果不大,所以索引其實還需要考慮下業務特點)

至於說為什麼聚集索引的速度一般要比非聚集的好,這個問題大家可以google下。留個小的共同探討的問題:)

以上為個人這段時間對mysql高效能-索引使用讀後的思考,不到之處,請多多指導,謝謝