国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

使用MYSQL索引

2024-07-24 12:55:44
字體:
來源:轉載
供稿:網友



    關系數據庫的世界是一個表與集合、表與集合上的運算占統(tǒng)治地位的世界。數據庫是一個表的集合,而表又是行和列的集合。在發(fā)布一條select 查詢從表中進行檢索行時,得到另一個行和列的集合。這些都是一些抽象的概念,對于數據庫系統(tǒng)用來操縱表中數據的基本
表示沒有多少參考價值。另一個抽象概念是,表上的運算都同時進行;查詢是一種概念性的集合運算,并且集合論中沒有時間概念。當然,現實世界是相當不同的。數據庫管理系統(tǒng)實現了抽象的概念,但是在實際的硬件
    范圍內要受到實際的物理約束。結牽檠ㄊ奔洌惺幣ê艸さ氖奔?。而人类呵{菀撞荒頭?,不喜欢祬s?,因此晤U嵌鋁思仙系哪切┧布淶氖г慫愕某橄笫瀾縟パ扒蠹鈾儼檠姆椒?。鹨哉f氖牽屑鋼旨鈾僭慫愕募際酰啥員斫興饕故菘夥衿韃檎倚懈???煽悸竊躚浞擲謎廡┧饕幢嘈床檠?殺嘈從跋旆衿韉鞫然頻牟檠估醋遠喔隹突щ牟檠韉酶謾n頤撬伎薊居布躚誦校員閬氤鱸躚朔湮錮碓際孕閱芙懈納頻姆椒ā?br>     這些正是本章所要討論的問題,其目標是優(yōu)化數據庫系統(tǒng)的性能,使其盡可能快地處理各種查詢。mysql已經相當快了,但即使是最快的數據庫,在人的設計下還能運行得更快。
    4.1使用索引
    我們首先討論索引,因為它是加快查詢的最重要的工具。還有其他加快查詢的技術,但是最有效的莫過于恰當地使用索引了。在mysql的郵件清單上,人們通常詢問關于使查詢更快的問題。在大量的案例中,都是因為表上沒有索引,一般只要加上索引就可以立即解決問題。但這樣也并非總是有效,因為優(yōu)化并非總是那樣簡單。然而,如果不使用索引,在許多情形下,用其他手段改善性能只會是浪費時間。應該首先考慮使用索引取得最大的性能改善,然后再尋求其他可能有幫助的技術。
    本節(jié)介紹索引是什么、它怎樣改善查詢性能、索引在什么情況下可能會降低性能,以及怎樣為表選擇索引。下一節(jié),我們將討論mysql的查詢優(yōu)化程序。除了知道怎樣創(chuàng)建索引外,了解一些優(yōu)化程序的知識也是有好處的,因為這樣可以更好地利用所創(chuàng)建的索引。某些編寫查詢的方法實際上會妨礙索引的效果,應該避免這種情況出現。(雖然并非總會這樣。有時也會希望忽略優(yōu)化程序的作用。我們也將介紹這些情況。)
    4.1.1索引的益處
    讓我們從一個無索引的表著手來考察索引是怎樣起作用的。無索引的表就是一個無序的行集。例如,圖4 - 1給出了我們在第1章“mysql與sql 介紹” 中首先看到的ad 表。這個表上沒有索引,因此如果我們查找某個特定公司的行時,必須查看表中的每一行,看它是否與所需的值匹配。這是一個全表掃描,很慢,如果表中只有少數幾個記錄與搜索條件相匹配,則其效率是相當低的。

    圖4 - 2給出了相同的表,但在表的company_num 列上增加了一個索引。此索引包含表中每行的一項,但此索引是在company_num 上排序的?,F在,不需要逐行搜索全表查找匹配的條款,而是可以利用索引進行查找。假如我們要查找公司13的所有行,那么可以掃描索引,結果得出3行。然后到達公司14的行,這是一個比我們正在查找的要大的號碼。索引值是排序的,因此在讀到包含14的記錄時,我們知道不會再有匹配的記錄,可以退出了。如果查找一個值,它在索引表中某個中間點以前不會出現,那么也有找到其第一個匹配索引項的定位算法,而不用進行表的順序掃描(如二分查找法)。這樣,可以快速定位到第一個匹配的值,以節(jié)省大量搜索時間。數據庫利用了各種各樣的快速定位索引值的技術,這些技術是什么并不重要,重要的是它們工作正常,索引技術是個好東西。
    有人會問,為什么不只對數據文件進行排序,省掉索引文件?這樣不也在搜索時產生相同的效果嗎?問得好,如果只有單個索引時,
是這樣的。不過有可能會用到第二個索引,但同時以兩種不同的方法對同一個數據文件進行排序是不可能的。(如,想要一個顧客名的索
引,同時又要一個顧客id 號或電話號碼的索引。)將索引文件作為一個與數據文件獨立的實體就解決了這個問題,而且允許創(chuàng)建多個索
引。此外,索引中的行一般要比數據文件中的行短。在插入或刪除值時,為保持排序順序而移動較短的索引值與移動較長的數據行相比更
為容易。

    這個例子與mysql索引表的方法相符。表的數據行保存在數據文件中,而索引值保存在索引文件中。一個表上可有不止一個索引;如果確實有不止一個索引,它們都保存在同一個索引文件中。索引文件中的每個索引由排過序的用來快速訪問數據文件的鍵記錄數組構成。
前面的討論描述了單表查詢中索引的好處,其中使用索引消除了全表掃描,極大地加快了搜索的速度。在執(zhí)行涉及多個表的連接查詢時,索引甚至會更有價值。在單個表的查詢中,每列需要查看的值的數目就是表中行的數目。而在多個表的查詢中,可能的組合數目極大,因為這個數目為各表中行數之積。
    假如有三個未索引的表t 1、t 2、t 3,分別只包含列c 1、c 2、c 3,每個表分別由含有數值1到1000 的1000 行組成。查找對應值相等的表行組合的查詢如下所示:
    select c1,c2,c3
    from t1,t2,t3
    where c1=c2 and c1=c3
    此查詢的結果應該為1000 行,每個組合包含3 個相等的值。如果我們在無索引的情況下處理此查詢,則不可能知道哪些行包含那些值。因此,必須尋找出所有組合以便得出與where 子句相配的那些組合??赡艿慕M合數目為10 0 0×10 0 0×10 0 0(十億),比匹配數目多一百萬倍。很多工作都浪費了,并且這個查詢將會非常慢,即使在如像mysql這樣快的數據庫中執(zhí)行也會很慢。而這還是每個表中只有1000 行的情形。如果每個表中有一百萬行時,將會怎樣?很顯然,這樣將會產生性能極為低下的結果。如果對每個表進行索引,就能極大地加速查詢進程,因為利用索引的查詢處理如下:
    1) 如下從表t1中選擇第一行,查看此行所包含的值。
    2) 使用表t2 上的索引,直接跳到t2 中與來自t1的值匹配的行。類似,利用表t3 上的索引,直接跳到t3 中與來自t1的值匹配的行。
    3) 進到表t1的下一行并重復前面的過程直到t1中所有的行已經查過。在此情形下,我們仍然對表t1執(zhí)行了一個完全掃描,但能夠在表t2 和t3 上進行索引查找直接取出這些表中的行。從道理上說,這時的查詢比未用索引時要快一百萬倍。如上所述,mysql利用索引加速了where 子句中與條件相配的行的搜索,或者說在執(zhí)行連接時加快了與其他表中的行匹配的行的搜索。它也利用索引來改進其他操作的性能:
    ■ 在使用min( ) 和max( ) 函數時,能夠快速找到索引列的最小或最大值。
    ■ mysql常常能夠利用索引來完成order by 子句的排序操作。
    ■ 有時,mysql可避免對整個數據文件的讀取。假如從一個索引數值列中選擇值,而且不選擇表中其他列。這時,通過對索引值的讀取,就已經得到了讀取數據文件所要得到的值。沒有對相同的值進行兩次讀取的必要,因此,甚至無需涉及數據文件。
    4.1.2 索引的弊端
    一般情況下,如果mysql能夠知道怎樣用索引來更快地處理查詢,它就會這樣做。這表示,在大多數情況下,如果您不對表進行索引,則損害的是您自己的利益。可以看出,作者描繪了索引的諸多好處。但有不利之處嗎?是的,有。實際上,這些缺點被優(yōu)點所掩蓋了,
但應該對它們有所了解。
    首先,索引文件要占磁盤空間。如果有大量的索引,索引文件可能會比數據文件更快地達到最大的文件尺寸。其次,索引文件加快了檢索,但增加了插入和刪除,以及更新索引列中的值的時間(即,降低了大多數涉及寫入的操作的時間),因為寫操作不僅涉及數據行,而且還常常涉及索引。一個表擁有的索引越多,則寫操作的平均性能下降就越大。在4 . 4節(jié)“有效地裝載數據”中,我們將更為詳細地介紹這些性能問題,并討論怎樣解決。
    4.1.3 選擇索引
    創(chuàng)建索引的語法已經在3 . 4 . 3節(jié)“創(chuàng)建和刪除索引”中進行了介紹。這里,我們假定您已經閱讀過該節(jié)。但是知道語法并不能幫助確定表怎樣進行索引。要決定表怎樣進行索引需要考慮表的使用方式。本節(jié)介紹一些關于怎樣確定和挑選索引列的準則:
    ■ 搜索的索引列,不一定是所要選擇的列。換句話說,最適合索引的列是出現在where 子句中的列,或連接子句中指定的列,而不是出現在select 關鍵字后的選擇列表中的列:


    當然,所選擇的列和用于where 子句的列也可能是相同的。關鍵是,列出現在選擇列表中不是該列應該索引的標志。出現在連接子句中的列或出現在形如col1= col2 的表達式中的列是很適合索引的列。查詢中的col_b 和col_c 就是這樣的例子。如果mysql能利用連接列來優(yōu)化一個查詢,表示它通過消除全表掃描相當可觀地減少了表行的組合。
    ■ 使用惟一索引??紤]某列中值的分布。對于惟一值的列,索引的效果最好,而具有多個重復值的列,其索引效果最差。例如,存放年齡的列具有不同值,很容易區(qū)分各行。而用來記錄性別的列,只含有“ m”和“f”,則對此列進行索引沒有多大用處(不管搜索哪個值,都會得出大約一半的行)。
    ■ 使用短索引。如果對串列進行索引,應該指定一個前綴長度,只要有可能就應該這樣做。例如,如果有一個char(200) 列,如果在前10 個或20 個字符內,多數值是惟一的,那么就不要對整個列進行索引。對前10 個或20 個字符進行索引能夠節(jié)省大量索引空間,也可能會使查詢更快。較小的索引涉及的磁盤i/o 較少,較短的值比較起來更快。更為重要的是,對于較短的鍵值,索引高速緩存中的塊能容納更多的鍵值,因此,mysql也可以在內存中容納更多的值。這增加了找到行而不用讀取索引中較多塊的可能性。(當然,應該利用一些常識。如僅用列值的第一個字符進行索引是不可能有多大好處的,因為這個索引中不會有許多不同的值。)
    ■ 利用最左前綴。在創(chuàng)建一個n 列的索引時,實際是創(chuàng)建了mysql可利用的n 個索引。多列索引可起幾個索引的作用,因為可利用索引中最左邊的列集來匹配行。這樣的列集稱為最左前綴。(這與索引一個列的前綴不同,索引一個列的前綴是利用該的前n 個字符作為索引值。)
    假如一個表在分別名為s t a t e、city 和zip 的三個列上有一個索引。索引中的行是按state/city/zip 的次序存放的,因此,索引中的行也會自動按state/city 的順序和state 的順序存放。這表示,即使在查詢中只指定state 值或只指定state 和city 的值,mysql也可以利用索引。因此,此索引可用來搜索下列的列組合:
    state,city,zip
    state,city
    sate
    mysql不能使用不涉及左前綴的搜索。例如,如果按city 或zip 進行搜索,則不能使用該索引。如果要搜索某個州以及某個zip 代碼(索引中的列1和列3),則此索引不能用于相應值的組合。但是,可利用索引來尋找與該州相符的行,以減少搜索范圍。
    ■ 不要過度索引。不要以為索引“越多越好”,什么東西都用索引是錯的。每個額外的索引都要占用額外的磁盤空間,并降低寫操作的性能,這一點我們前面已經介紹過。在修改表的內容時,索引必須進行更新,有時可能需要重構,因此,索引越多,所花的時間越長。如果有一個索引很少利用或從不使用,那么會不必要地減緩表的修改速度。此外,mysql在生成一個執(zhí)行計劃時,要考慮各個索引,這也要費時間。創(chuàng)建多余的索引給查詢優(yōu)化帶來了更多的工作。索引太多,也可能會使mysql選擇不到所要使用的最好索引。只保持所需的索引有利于查詢優(yōu)化。如果想給已索引的表增加索引,應該考慮所要增加的索引是否是現有多列索引的最左索引。如果是,則就不要費力去增加這個索引了,因為已經有了。
    ■ 考慮在列上進行的比較類型。索引可用于“ <”、“ < = ”、“ = ”、“ > =”、“ > ”和between 運算。在模式具有一個直接量前綴時,索引也用于like 運算。如果只將某個列用于其他類型的運算時(如strcmp( )),對其進行索引沒有價值。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 朝阳区| 乐平市| 江川县| 宜昌市| 陵川县| 崇义县| 忻州市| 乌兰县| 济宁市| 分宜县| 依兰县| 西安市| 长治县| 五寨县| 红河县| 耿马| 昌平区| 石首市| 孝感市| 政和县| 天气| 老河口市| 板桥市| 米脂县| 河曲县| 海安县| 慈利县| 尼玛县| 大城县| 锡林浩特市| 辰溪县| 珲春市| 伊金霍洛旗| 文登市| 铜陵市| 奇台县| 肇东市| 巴南区| 虞城县| 岗巴县| 剑河县|