• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            一、什么是索引?

              索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執(zhí)行查詢時(shí)MySQL必須從第一個(gè)記錄開始掃描整 個(gè)表的所有記錄,直至找到符合要求的記錄。表里面的記錄數(shù)量越多,這個(gè)操作的代價(jià)就越高。如果作為搜索條件的列上已經(jīng)創(chuàng)建了索引,MySQL無需掃描任何 記錄即可迅速得到目標(biāo)記錄所在的位置。如果表有1000個(gè)記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。

              假設(shè)我們創(chuàng)建了一個(gè)名為people的表:

            CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );

              然后,我們完全隨機(jī)把1000個(gè)不同name值插入到people表。下圖顯示了people表所在數(shù)據(jù)文件的一小部分:


            點(diǎn)擊查看原圖

              可以看到,在數(shù)據(jù)文件中name列沒有任何明確的次序。如果我們創(chuàng)建了name列的索引,MySQL將在索引中排序name列:

            點(diǎn)擊查看原圖

              對(duì)于索引中的每一項(xiàng),MySQL在內(nèi)部為它保存一個(gè)數(shù)據(jù)文件中實(shí)際記錄所在位置的“指針”。因此,如果我們要查找name等于“Mike”記錄的 peopleid(SQL命令為“SELECT peopleid FROM people WHERE name=\'Mike\';”),MySQL能夠在name的索引中查找“Mike”值,然后直接轉(zhuǎn)到數(shù)據(jù)文件中相應(yīng)的行,準(zhǔn)確地返回該行的 peopleid(999)。在這個(gè)過程中,MySQL只需處理一個(gè)行就可以返回結(jié)果。如果沒有“name”列的索引,MySQL要掃描數(shù)據(jù)文件中的所有 記錄,即1000個(gè)記錄!顯然,需要MySQL處理的記錄數(shù)量越少,則它完成任務(wù)的速度就越快。

              二、索引的類型

              MySQL提供多種索引類型供選擇:
            • 普通索引

              這是最基本的索引類型,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式創(chuàng)建:

              • 創(chuàng)建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
              • 修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
              • 創(chuàng)建表的時(shí)候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );

            • 唯一性索引

              這種索引和前面的“普通索引”基本相同,但有一個(gè)區(qū)別:索引列的所有值都只能出現(xiàn)一次,即必須唯一。唯一性索引可以用以下幾種方式創(chuàng)建:

              • 創(chuàng)建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
              • 修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
              • 創(chuàng)建表的時(shí)候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );

            • 主鍵

              主鍵是一種唯一性索引,但它必須指定為“PRIMARY KEY”。如果你曾經(jīng)用過AUTO_INCREMENT類型的列,你可能已經(jīng)熟悉主鍵之類的概念了。主鍵一般在創(chuàng)建表的時(shí)候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我們也可以通過修改表的方式加入主鍵,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每個(gè)表只能有一個(gè)主鍵。
               
            • 全文索引

              MySQL從3.23.23版開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型為FULLTEXT。全文索引可以在VARCHAR或者 TEXT類型的列上創(chuàng)建。它可以通過CREATE TABLE命令創(chuàng)建,也可以通過ALTER TABLE或CREATE INDEX命令創(chuàng)建。對(duì)于大規(guī)模的數(shù)據(jù)集,通過ALTER TABLE(或者CREATE INDEX)命令創(chuàng)建全文索引要比把記錄插入帶有全文索引的空表更快。本文下面的討論不再涉及全文索引,要了解更多信息,請(qǐng)參見MySQL documentation
              三、單列索引與多列索引

              索引可以是單列索引,也可以是多列索引。下面我們通過具體的例子來說明這兩種索引的區(qū)別。假設(shè)有這樣一個(gè)people表:

            ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

              由于索引文件以B-樹格式保存,MySQL能夠立即轉(zhuǎn)到合適的firstname,然后再轉(zhuǎn)到合適的lastname,最后轉(zhuǎn)到合適的age。在沒有掃描數(shù)據(jù)文件任何一個(gè)記錄的情況下,MySQL就正確地找出了搜索的目標(biāo)記錄!

              那么,如果在firstname、lastname、age這三個(gè)列上分別創(chuàng)建單列索引,效果是否和創(chuàng)建一個(gè)firstname、lastname、 age的多列索引一樣呢?答案是否定的,兩者完全不同。當(dāng)我們執(zhí)行查詢的時(shí)候,MySQL只能使用一個(gè)索引。如果你有三個(gè)單列的索引,MySQL會(huì)試圖選 擇一個(gè)限制最嚴(yán)格的索引。但是,即使是限制最嚴(yán)格的單列索引,它的限制能力也肯定遠(yuǎn)遠(yuǎn)低于firstname、lastname、age這三個(gè)列上的多列 索引。

              四、最左前綴

              多列索引還有另外一個(gè)優(yōu)點(diǎn),它通過稱為最左前綴(Leftmost Prefixing)的概念體現(xiàn)出來。繼續(xù)考慮前面的例子,現(xiàn)在我們有一個(gè)firstname、lastname、age列上的多列索引,我們稱這個(gè)索引 為fname_lname_age。當(dāng)搜索條件是以下各種列的組合時(shí),MySQL將使用fname_lname_age索引:
            • firstname,lastname,age
            • firstname,lastname
            • firstname
              從另一方面理解,它相當(dāng)于我們創(chuàng)建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都能夠使用這個(gè)fname_lname_age索引:
             
            table type possible_keys key key_len ref rows Extra
            people ref fname_lname_age fname_lname_age 102 const,const,const 1 Where used

              下面我們就來看看這個(gè)EXPLAIN分析結(jié)果的含義。
            • table:這是表的名字。

            • type:連接操作的類型。下面是MySQL文檔關(guān)于ref連接類型的說明:

              “對(duì)于每一種與另一個(gè)表中記錄的組合,MySQL將從當(dāng)前的表讀取所有帶有匹配索引值的記錄。如果連接操作只使用鍵的最左前綴,或者如果鍵不是 UNIQUE或PRIMARY KEY類型(換句話說,如果連接操作不能根據(jù)鍵值選擇出唯一行),則MySQL使用ref連接類型。如果連接操作所用的鍵只匹配少量的記錄,則ref是一 種好的連接類型。”

              在本例中,由于索引不是UNIQUE類型,ref是我們能夠得到的最好連接類型。

              如果EXPLAIN顯示連接類型是“ALL”,而且你并不想從表里面選擇出大多數(shù)記錄,那么MySQL的操作效率將非常低,因?yàn)樗獟呙枵麄€(gè)表。你可以加入更多的索引來解決這個(gè)問題。預(yù)知更多信息,請(qǐng)參見MySQL的手冊(cè)說明。

            • possible_keys

              可能可以利用的索引的名字。這里的索引名字是創(chuàng)建索引時(shí)指定的索引昵稱;如果索引沒有昵稱,則默認(rèn)顯示的是索引中第一個(gè)列的名字(在本例中,它是“firstname”)。默認(rèn)索引名字的含義往往不是很明顯。

            • Key

              它顯示了MySQL實(shí)際使用的索引的名字。如果它為空(或NULL),則MySQL不使用索引。

            • key_len

              索引中被使用部分的長(zhǎng)度,以字節(jié)計(jì)。在本例中,key_len是102,其中firstname占50字節(jié),lastname占50字節(jié),age占2字節(jié)。如果MySQL只使用索引中的firstname部分,則key_len將是50。

            • ref

              它顯示的是列的名字(或單詞“const”),MySQL將根據(jù)這些列來選擇行。在本例中,MySQL根據(jù)三個(gè)常量選擇行。

            • rows

              MySQL所認(rèn)為的它在找到正確的結(jié)果之前必須掃描的記錄數(shù)。顯然,這里最理想的數(shù)字就是1。

            • Extra

              這里可能出現(xiàn)許多不同的選項(xiàng),其中大多數(shù)將對(duì)查詢產(chǎn)生負(fù)面影響。在本例中,MySQL只是提醒我們它將用WHERE子句限制搜索結(jié)果集。
              七、索引的缺點(diǎn)

              到目前為止,我們討論的都是索引的優(yōu)點(diǎn)。事實(shí)上,索引也是有缺點(diǎn)的。

              首先,索引要占用磁盤空間。通常情況下,這個(gè)問題不是很突出。但是,如果你創(chuàng)建每一種可能列組合的索引,索引文件體積的增長(zhǎng)速度將遠(yuǎn)遠(yuǎn)超過數(shù)據(jù)文件。如果你有一個(gè)很大的表,索引文件的大小可能達(dá)到操作系統(tǒng)允許的最大文件限制。

              第二,對(duì)于需要寫入數(shù)據(jù)的操作,比如DELETE、UPDATE以及INSERT操作,索引會(huì)降低它們的速度。這是因?yàn)镸ySQL不僅要把改動(dòng)數(shù)據(jù)寫入數(shù)據(jù)文件,而且它還要把這些改動(dòng)寫入索引文件。

              【結(jié)束語】

              在大型數(shù)據(jù)庫中,索引是提高速度的一個(gè)關(guān)鍵因素。不管表的結(jié)構(gòu)是多么簡(jiǎn)單,一次500000行的表掃描操作無論如何不會(huì)快。如果你的網(wǎng)站上也有這種大規(guī)模的表,那么你確實(shí)應(yīng)該花些時(shí)間去分析可以采用哪些索引,并考慮是否可以改寫查詢以優(yōu)化應(yīng)用。要了解更多信息,請(qǐng)參見MySQL manual。另外注意,本文假定你所使用的MySQL是3.23版,部分查詢不能在3.22版MySQL上執(zhí)行。

            轉(zhuǎn)自:
            http://space.itpub.net/47598/viewspace-329730
            posted on 2009-11-24 17:00 chatler 閱讀(244) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Database
            <2009年10月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久久久无码精品| 精品久久8x国产免费观看| 东京热TOKYO综合久久精品 | 91精品日韩人妻无码久久不卡| 欧美精品九九99久久在观看| 品成人欧美大片久久国产欧美...| 国产精品久久久久久搜索| 国内精品久久久久久99| 久久国产精品无码一区二区三区| 性做久久久久久久| 精品国产一区二区三区久久久狼| 久久综合综合久久综合| 久久久无码精品亚洲日韩按摩 | 久久综合丝袜日本网| 国产亚洲美女精品久久久久狼| 国产国产成人精品久久| 91麻豆精品国产91久久久久久| 99久久www免费人成精品 | 久久青青草原精品国产软件| 久久亚洲AV无码西西人体| 欧美亚洲国产精品久久高清| 亚洲国产精品无码久久一区二区| 日产精品99久久久久久| 88久久精品无码一区二区毛片 | 青青草原综合久久| 狠狠色综合网站久久久久久久| 亚洲精品综合久久| 久久久久久毛片免费播放| 国产精品九九久久免费视频 | 久久精品免费全国观看国产| 亚洲国产精品久久电影欧美| 久久青青草原综合伊人| 色婷婷久久久SWAG精品| 人妻精品久久久久中文字幕69 | 国产精品亚洲综合专区片高清久久久 | 94久久国产乱子伦精品免费| 思思久久精品在热线热| 国内精品久久国产大陆| 久久无码专区国产精品发布| 久久精品成人国产午夜| 99久久无色码中文字幕人妻|