2007年9月22日

          用一個(gè)例子詳細(xì)說(shuō)明單列索引與組合索引的區(qū)別及索引使用中的一些細(xì)節(jié)

          建一個(gè)表:
          CREATE TABLE myIndex (

          i_testID INT NOT NULL AUTO_INCREMENT,

          vc_Name VARCHAR(50) NOT NULL,

          vc_City VARCHAR(50) NOT NULL,

          i_Age INT NOT NULL,

          i_SchoolID INT NOT NULL,

          PRIMARY KEY (i_testID)

          );

            假設(shè)這個(gè)表中有10000條記錄,其中很分散地分布了5vc_Name="erquan"的記錄,只不過(guò)city,age,school的組合各不相同。
            
          來(lái)看這條T-SQL
                    SELECT i_testID FROM myIndex WHERE vc_Name='erquan' AND vc_City='beijing
          ' AND i_Age=25;

              
          首先考慮建單列索引:
              
          vc_Name列上建立了索引。執(zhí)行T-SQL時(shí),MYSQL很快將目標(biāo)鎖定在了vc_Name=erquan5條記錄上,取出來(lái)放到一中間 結(jié)果集。在這個(gè)結(jié)果集里,先排除掉vc_City不等于"beijing"的記錄,再排除i_Age不等于25的記錄,最后篩選出唯一的符合條件的記錄。

              
          雖然在vc_Name上建立了索引,查詢時(shí)MYSQL不用掃描整張表,效率有所提高,但離我們的要求還有一定的距離。同樣的,在vc_Cityi_Age分別建立的單列索引的效率相似。

              
          為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。就是將vc_Name,vc_City,i_Age建到一個(gè)索引里:
                    ALTER TABLE myIndex ADD INDEX name_city_age (vc_Name(10),vc_City,i_Age);--
          注意了,建表時(shí),vc_Name長(zhǎng)度為50,這里為什么用10呢?因?yàn)橐话闱闆r下名字的長(zhǎng) 度不會(huì)超過(guò)10,這樣會(huì)加速索引查詢速度,還會(huì)減少索引文件的大小,提高INSERT的更新速度。

              
          執(zhí)行T-SQL時(shí),MySQL無(wú)須掃描任何記錄就到找到唯一的記錄!

              
          肯定有人要問(wèn)了,如果分別在vc_Name,vc_City,i_Age上建立單列索引,讓該表有3個(gè)單列索引,查詢時(shí)和上述的組合索引效率一樣 吧?嘿嘿,大不一樣,遠(yuǎn)遠(yuǎn)低于我們的組合索引~~雖然此時(shí)有了三個(gè)索引,但MySQL只能用到其中的那個(gè)它認(rèn)為似乎是最有效率的單列索引。

              
          建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了
                        vc_Name,vc_City,i_Age
                        vc_Name,vc_City
                        vc_Name
              
          這樣的三個(gè)組合索引為什么沒(méi)有vc_City,i_Age等這樣的組合索引的效率呢?這是因?yàn)?/span>mysql組合索引"最左前綴"的結(jié)果。簡(jiǎn)單的理解就是只從最左面的開(kāi)始組合。并不是只要包含這三列的查詢都會(huì)用到該組合索引,下面的幾個(gè)T-SQL會(huì)用到:
                    SELECT * FROM myIndex WHREE vc_Name="erquan" AND vc_City="beijing
          "
                    SELECT * FROM myIndex WHREE vc_Name="erquan"
          而下面幾個(gè)則不會(huì)用到:
                    SELECT * FROM myIndex WHREE i_Age=20 AND vc_City="beijing
          "
                    SELECT * FROM myIndex WHREE vc_City="beijing
          "

                    但什么情況下需要建立索引呢?一般來(lái)說(shuō),在WHERE和JOIN中出現(xiàn)的列需要建立索引,但也不完全如此,因?yàn)镸ySQL只對(duì) <,<=,=,>,>=,BETWEEN,IN,以及某些時(shí)候的LIKE才會(huì)使用索引。
          SELECT t.vc_Name FROM testIndex t LEFT JOIN myIndex m ON t.vc_Name=m.vc_Name WHERE m.i_Age=20 AND m.vc_City='beijing' 時(shí),有對(duì)myIndex表的vc_City和i_Age建立索引的需要,由于testIndex表的vc_Name開(kāi)出現(xiàn)在了JOIN子句中,也有對(duì)它建立索引的必要。

            剛才提到只有某些時(shí)候的LIKE才需建立索引?是的。因?yàn)樵谝酝ㄅ浞?% 和 _ 開(kāi)頭作查詢時(shí),MySQL不會(huì)使用索引,如
          SELECT * FROM myIndex WHERE vc_Name like'erquan%'
          會(huì)使用索引,而
          SELECT * FROM myIndex WHEREt vc_Name like'%erquan'
          就不會(huì)使用索引了。

          posted @ 2007-09-22 23:19 擦肩而過(guò) 閱讀(308) | 評(píng)論 (0)編輯 收藏

          普通MySQL運(yùn)行,數(shù)據(jù)量和訪問(wèn)量不大的話,是足夠快的,但是當(dāng)數(shù)據(jù)量和訪問(wèn)量劇增的時(shí)候,那么就會(huì)明顯發(fā)現(xiàn)MySQL很慢,甚至down掉,那么就要考慮優(yōu)化我們的MySQL了,其中優(yōu)化MYSQL的一個(gè)重要環(huán)節(jié)就是為數(shù)據(jù)庫(kù)建立正確合理的索引。

          如果沒(méi)有索引,執(zhí)行查詢時(shí)MySQL必須從第一個(gè)記錄開(kāi)始掃描整個(gè)表的所有記錄,直至找到符合要求的記錄。表里面的記錄數(shù)量越多,這個(gè)操作的代價(jià)就越高。如果作為搜索條件的列上已經(jīng)創(chuàng)建了索引,MySQL無(wú)需掃描任何記錄即可迅速得到目標(biāo)記錄所在的位置。也就是說(shuō)索引可以大大減少數(shù)據(jù)庫(kù)管理系統(tǒng)查找數(shù)據(jù)的時(shí)間。索引有哪些優(yōu)點(diǎn)?

          1、  通過(guò)創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。

          2、  可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要原因。

          3、  可以加速表和表之間的連接,這在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。

          4、  在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。

           索引有哪些缺點(diǎn)?

          1、  創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加。

          2、  除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個(gè)索引還要占一定的物理空間,如果要建立聚簇索引,需要的空間就會(huì)更大。

          3、  當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度。

           索引有哪些類型?

          1、 普通索引

          這是最基本的索引類型,而且它沒(méi)有唯一性之類的限制。

          2、 唯一性索引

          這種索引和前面的普通索引基本相同,但有一個(gè)區(qū)別:索引列的所有值都只能出現(xiàn)一次,即必須唯一。

          3、主鍵

          它是一種特殊的唯一索引,不允許有空值。

          4、全文索引

          MySQL3.23.23版開(kāi)始支持全文索引和全文檢索。

           單列索引和組合索引:

          單列索引就是把索引單獨(dú)建立在一個(gè)字段上。

          組合索引復(fù)合索引就是一個(gè)索引創(chuàng)建在兩個(gè)列或者多個(gè)列上。在搜索時(shí),當(dāng)兩個(gè)或者多個(gè)列作為一個(gè)關(guān)鍵值時(shí),最好在這些列上創(chuàng)建復(fù)合索引。

           建立和使用索引有哪些注意事項(xiàng):

          1、           索引要建立在經(jīng)常進(jìn)行select操作的字段上這是因?yàn)椋绻@些列很少用到,那么有無(wú)索引并不能明顯改變查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護(hù)速度和增大了空間需求。

          2、           索引要建立在值比較唯一的字段上。這樣做才是發(fā)揮索引的最大效果。比如主鍵的id字段,唯一的名字name字段等等。如果索引建立在唯一值比較少的字段,比如性別gender字段,寥寥無(wú)幾的類別字段等,剛索引幾乎沒(méi)有任何意義。

          3、           對(duì)于那些定義為text imagebit數(shù)據(jù)類型的列不應(yīng)該增加索引。因?yàn)檫@些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少。

          4、           當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時(shí),不應(yīng)該創(chuàng)建索引。修改性能和檢索性能是互相矛盾的。當(dāng)增加索引時(shí),會(huì)提高檢索性能,但是會(huì)降低修改性能。當(dāng)減少索引時(shí),會(huì)提高修改性能,降低檢索性能。因此,當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時(shí),不應(yīng)該創(chuàng)建索引。

          5、           WHEREJOIN中出現(xiàn)的列需要建立索引。

          6、           在以通配符 % _ 開(kāi)頭作查詢時(shí),MySQL索引是無(wú)效的。但是這樣索引是有效的:select * from tbl1 where name like 'xxx%',所以謹(jǐn)慎的寫你的SQL是很重要的。

          posted @ 2007-09-22 23:18 擦肩而過(guò) 閱讀(403) | 評(píng)論 (0)編輯 收藏


          僅列出標(biāo)題  

          posts - 2, comments - 0, trackbacks - 0, articles - 0

          Copyright © 擦肩而過(guò)

          主站蜘蛛池模板: 从江县| 汤原县| 信宜市| 邯郸县| 纳雍县| 卢龙县| 新化县| 五峰| 莲花县| 陆丰市| 安多县| 璧山县| 崇信县| 永登县| 托克逊县| 德化县| 平陆县| 吉木萨尔县| 大石桥市| 巢湖市| 鄂尔多斯市| 沙河市| 佛山市| 定陶县| 嘉禾县| 岢岚县| 浪卡子县| 慈溪市| 平山县| 明溪县| 广州市| 罗平县| 榆社县| 郑州市| 耒阳市| 纳雍县| 嵩明县| 马龙县| 兴海县| 千阳县| 易门县|