MySQL建立索引的基礎規則

1、mysql索引(基礎與規則)

索引規則:

一、 MySQL建表,字段需設置爲非空,需設置字段默認值。

二、 MySQL建表,字段需NULL時,需設置字段默認值,默認值不爲NULL

三、 MySQL建表,如果字段等價於外鍵,應在該字段加索引。

四、 MySQL建表,不同表之間的相同屬性值的字段,列類型,類型長度,是否非空,是否默認值,需保持一致,否則無法正確使用索引進行關聯對比。

五、 MySQL使用時,一條SQL語句只能使用一個表的一個索引。所有的字段類型都可以索引,多列索引的屬性最多15個。

六、 如果可以在多個索引中進行選擇,MySQL通常使用找到最少行的索引,索引唯一值最高的索引。

七、 建立索引indexpart1,part2,part3,相當於建立了index(part1),index(part1,part2)indexpart1,part2,part3)三個索引。

八、 MySQL針對like語法必須如下格式才使用索引:SELECT * FROM t1    WHERE key_col LIKE 'ab%' 

九、 SELECT COUNT(*) 語法在沒有where條件的語句中執行效率沒有SELECT COUNT(col_name)快,但是在有where條件的語句中執行效率要快。

十、 where條件中多個and的條件中,必須都是一個多列索引的key_part屬性而且必須包含key_part1。各自單一索引的話,只使用遍歷最少行的那個索引。

十一、 where條件中多個or的條件中,每一個條件,都必須是一個有效索引。

十二、 ORDER BY 後面的條件必須是同一索引的屬性,排序順序必須一致(比如都是升序或都是降序)。

十三、 所有GROUP BY列引用同一索引的屬性,並且索引必須是按順序保存其關鍵字的。

十四、 JOIN 索引,所有匹配ONwhere的字段應建立合適的索引。

十五、 對智能的掃描全表使用FORCE INDEX告知MySQL,使用索引效率更高。

十六、 定期ANALYZE TABLE tbl_name爲掃描的表更新關鍵字分佈 

十七、 定期使用慢日誌檢查語句,執行explain,分析可能改進的索引。

十八、 條件允許的話,設置較大的key_buffer_sizequery_cache_size的值(全局參數),和sort_buffer_size的值(session變量,建議不要超過4M)。

 

首先分析項目的數據表,都會有什麼樣的操作,比如產品列表,會按照分類、品牌等做where,按照時間、價格等排序(order by),所以做索引,個人覺得應該是按照業務邏輯去做。

 

索引類型:

(1)  普通索引

最簡單的索引方式,沒有太多的約束,創建方式如下:

創建:create index indexname on tablename(column(length));如果是字符型的字段,要指定length

(建表時指定)create table tablename ([….],index [indexname] (column(length));

修改:alter tablename add index [indexname] on (column(length))

刪除:drop index indexname on tablename

(2)  唯一索引

和普通索引的區別就是列值要唯一,允許有空值。(組合索引那組合後的列值也必須唯一)

創建:create unique index indexname on tablename (column(length))

              (健表時指定)create table ([….],unique [indexname] (column(length)))

修改:alter tablename add unique [indexname] on (column(length))

(3)  主鍵索引

主鍵索引就比較清晰了,大家經常用到,只需要記住兩個概念就行了,不能爲空,列值唯一。

當然了,還有就是一個表只能有一個主鍵。

(4)  全文索引

Mysql3.23開始支持全文索引,在項目中還真沒用過,都用了sphinx全文檢索了。所以在此不贅述了。

 

單列索引和組合索引

爲了描述這兩個概念,我們首先建一張測試表

Create table student(

Id int not null auto_increment primary key,

Name char(100) not null,

Age tinyint not null,

Score tinyint not null default 0

)engine=myisam default charset=gbk;

測試表名爲student,字段name是名字,age是年齡,score是成績。

 

現在有這麼一條查詢語句:select id from student where name=’arkulo’ and age=20 and score=90;

 

首先分析單列索引:

如果在nameagescore的每個字段上建立索引,那就會產生三個結果集,然後再取其交集,最後在得出查詢結果

 

組合索引:

Alter table student add index name_age_score on (name(10),age,score);

建立組合索引,其中name(10),只提取名稱的前部分,既能減少索引文件的體積,又能加快插入操作。

有了組合索引,就相當於有了如下三個索引:

(name,age,socre)

(name,age)

(name)

這也就是通常所說的“最左前綴”的概念,其實說簡單點就是要按照索引的順序進行排列

如果有了這個組合索引,那上面那條查詢語句一次即可命中

 

什麼時候用索引

首先mysql只對<,<=,=,>=,>,between,in,like使用索引,因此wherejoin(on)的時候就應該考慮到使用什麼樣的索引,而且要記住一條sql語句只能使用一個索引,比如有whereorder by同時出現的時候,order by 即使用的是索引字段,他也不會走索引。

 

索引的弱點

(1)   加了索引之後,那insertdeleteupdate操作都要更新索引,會造成一些附加操作

(2)   索引是保存在物理文件(.MYI)裏的,所以如果在一張大表上創建索引,勢必會造成索引文件也比較大


2、MySQL優化之索引創建規則

  1. 表的主鍵、外鍵必須有索引;

  2. 數據量超過300的表應該有索引;

  3. 經常與其他表進行連接的表,在連接字段上應該建立索引;

  4. 經常出現在Where子句中的字段,特別是大表的字段,應該建立索引;

  5. 索引應該建在選擇性高的字段上;

  6. 索引應該建在小字段上,對於大的文本字段甚至超長字段,不要建索引;

  7. 複合索引的建立需要進行仔細分析;儘量考慮用單字段索引代替:

    1. 正確選擇複合索引中的主列字段,一般是選擇性較好的字段;

    2. 複合索引的幾個字段是否經常同時以AND方式出現在Where子句中?單字段查詢是否極少甚至沒有?如果是,則可以建立複合索引;否則考慮單字段索引;

    3. 如果複合索引中包含的字段經常單獨出現在Where子句中,則分解爲多個單字段索引;

    4. 如果複合索引所包含的字段超過3個,那麼仔細考慮其必要性,考慮減少複合的字段;

    5. 如果既有單字段索引,又有這幾個字段上的複合索引,一般可以刪除複合索引;

  8. 頻繁進行數據操作的表,不要建立太多的索引;

  9. 刪除無用的索引,避免對執行計劃造成負面影響;

以上是一些普遍的建立索引時的判斷依據。一言以蔽之,索引的建立必須慎重,對每個索引的必要性都應該經過仔細分析,要有建立的依據。因爲太多的索引 與不充分、不正確的索引對性能都毫無益處:在表上建立的每個索引都會增加存儲開銷,索引對於插入、刪除、更新操作也會增加處理上的開銷。另外,過多的複合 索引,在有單字段索引的情況下,一般都是沒有存在價值的;相反,還會降低數據增加刪除時的性能,特別是對頻繁更新的表來說,負面影響更大。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章