• <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>
            隨筆 - 224  文章 - 41  trackbacks - 0
            <2010年10月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            享受編程

            常用鏈接

            留言簿(11)

            隨筆分類(159)

            隨筆檔案(224)

            文章分類(2)

            文章檔案(4)

            經(jīng)典c++博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

                原文地址:

            explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優(yōu)化的查詢語句。

                 使用方法,在select語句前加上explain就可以了:
            如:explain select surname,first_name form a,b where a.id=b.id

            分析結(jié)果形式如下:


            EXPLAIN列的解釋:
            table
            顯示這一行的數(shù)據(jù)是關(guān)于哪張表的

            type
            這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和ALL

            possible_keys
            顯示可能應(yīng)用在這張表中的索引。如果為空,沒有可能的索引。可以為相關(guān)的域從WHERE語句中選擇一個合適的語句

            key
            實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優(yōu)化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

            key_len
            使用的索引的長度。在不損失精確性的情況下,長度越短越好

            ref
            顯示索引的哪一列被使用了,如果可能的話,是一個常數(shù)

            rows
            MYSQL認為必須檢查的用來返回請求數(shù)據(jù)的行數(shù)

            Extra
            關(guān)于MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這里可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結(jié)果是檢索會很慢
            extra列返回的描述的意義

            Distinct
            一旦MYSQL找到了與行相聯(lián)合匹配的行,就不再搜索了

            Not exists
             
            MYSQL優(yōu)化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標(biāo)準(zhǔn)的行,
            就不再搜索了

            Range checked for each
            Record(index map:#)
             
            沒有找到理想的索引,因此對于從前面表中來的每一個
            行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。
            這是使用索引的最慢的連接之一
            Using filesort
             
            看到這個的時候,查詢就需要優(yōu)化了。MYSQL需要進行額外的步驟
            來發(fā)現(xiàn)如何對返回的行排序。它根據(jù)連接類型以及存儲排序鍵值和
            匹配條件的全部行的行指針來排序全部行

            Using index
             
            列數(shù)據(jù)是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,
            這發(fā)生在對表的全部的請求列都是同一個索引的部分的時候

            Using temporary
             
            看到這個的時候,查詢需要優(yōu)化了。
            這里,MYSQL需要創(chuàng)建一個臨時表來存儲結(jié)果,
            這通常發(fā)生在對不同的列集進行ORDER BY上,而不是GROUP BY上

            Where used
             
            使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。
            如果不想返回表中的全部行,并且連接類型ALL或index,這就會發(fā)生,
            或者是查詢有問題
             
            不同連接類型的解釋(按照效率高低的順序排序)
            system
            表只有一行:system表。這是const連接類型的特殊情況

            const
             
            表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因為只有一行,這個值實際就是常數(shù),因為MYSQL先讀這個值然后把它當(dāng)做常數(shù)來對待

            eq_ref
             
            在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯(lián)合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用

            ref
             
            這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發(fā)生。對于之前的表的每一個行聯(lián)合,全部記錄都將從表中讀出。這個類型嚴(yán)重依賴于根據(jù)索引匹配的記錄多少—越少越好

            range
             
            這個連接類型使用索引返回一個范圍中的行,比如使用>或<查找東西時發(fā)生的情況

            index
             
            這個連接類型對前面的表中的每一個記錄聯(lián)合進行完全掃描(比ALL更好,因為索引一般小于表數(shù)據(jù))

            ALL

            這個連接類型對于前面的每一個記錄聯(lián)合進行完全掃描,這一般比較糟糕,應(yīng)該盡量避免

            ppt地址:
            http://www.slideshare.net/sky000/mysql-explain

            MySQL之Explain
            原文地址:http://hi.baidu.com/thinkinginlamp/blog/item/eef0cd119239db17b8127b6f.html

            前記:很多東西看似簡單,那是因為你并未真正了解它。

            Explain命令用于查看執(zhí)行效果。雖然這個命令只能搭配select類型語句使用,如果你想查看update,delete類型語句中的索引效果,也不是太難的事情,只要保持條件不變,把類型轉(zhuǎn)換成select就行了。

            explain的語法如下:

            explain [extended] select ... from ... where ...

            如果使用了extended,那么在執(zhí)行完explain語句后,可以使用show warnings語句查詢相應(yīng)的優(yōu)化信息。

            ==============================================================

            mk-visual-explain工具擴展了explain,它提供了一種更直觀的樹形表現(xiàn)形式,使用方法很簡單:

            mk-visual-explain <file_containing_explain_output>
            mk-visual-explain -c <file_containing_query>
            mysql -e "explain select * from mysql.user" | mk-visual-explain


            也可以在MySQL命令行里通過設(shè)置pager的方式來執(zhí)行:

            mysql> pager mk-visual-explain
            mysql> explain [extended] select ... from ... where ...


            ==============================================================

            進入正題,為了讓例子更具體化,我們先來建一個表,插入一點測試數(shù)據(jù):

            CREATE TABLE IF NOT EXISTS `article` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `author_id` int(10) unsigned NOT NULL,
            `category_id` int(10) unsigned NOT NULL,
            `views` int(10) unsigned NOT NULL,
            `comments` int(10) unsigned NOT NULL,
            `title` varbinary(255) NOT NULL,
            `content` text NOT NULL,
            PRIMARY KEY (`id`)
            );

            INSERT INTO `article`
            (`author_id`, `category_id`
            , `views`, `comments`, `title`, `content`) VALUES
            (1, 1, 
            1, 1, '1', '1'),
            (2, 2, 2, 
            2, '2', '2');

            缺省只建了一個主鍵,沒有建其他的索引。測試時,如果你時間充裕,應(yīng)該盡可能插入多一點的測試數(shù)據(jù),怎么說也應(yīng)該保證幾千條。如果數(shù)據(jù)量過少,可能會影響MySQL在索引選擇上的判斷。如此一來,一旦產(chǎn)品上線,數(shù)據(jù)量增加。索引往往不會按照你的預(yù)想工作。

            下面讓我們設(shè)置一個任務(wù):查詢category_id為1且comments大于1的情況下,views最多的article_id。

            問題很簡單,SQL也很簡單:

            SELECT author_id
            FROM `article`
            WHERE category_id = 1 AND comments > 1
            ORDER BY views DESC
            LIMIT 1


            下面讓我們用explain命令查看索引效果:

            EXPLAIN SELECT author_id
            FROM `article`
            WHERE category_id = 1
            AND comments > 1
            ORDER BY views DESC
            LIMIT 1


            這時explain部分結(jié)果如下:

            type: ALL
            key: NULL
            Extra: Using where; Using filesort


            顯示數(shù)據(jù)庫進行了全表掃描,沒有用到索引,并且在過程中文件排序。這樣的結(jié)果肯定是糟糕的,下面讓我們通過建立索引優(yōu)化一下它:

            ALTER TABLE `article` ADD INDEX x ( `category_id` , `comments`, `views` ) ;


            這時explain部分結(jié)果如下:

            type: range
            key: x
            Extra: Using where; Using filesort


            雖然不再是全表掃描了,但是仍然存在文件排序。一般來說,文件排序都是由于ORDER BY語句一起的,而我們已經(jīng)把views字段放到了聯(lián)合索引里面,為什么沒有效果呢?這是因為按照BTree的工作原理,先排序category_id,如果遇到相同的category_id則再排序comments,如果遇到相同的comments則再排序views。當(dāng)comments字段在聯(lián)合索引里處于中間位置時,因為comments > 1條件是一個范圍值(所謂range),MySQL目前無法利用索引再對后面的views部分進行檢索,如果換成是是comments in ('a', 'b', 'c')這樣的多等情況則可以,關(guān)于這一點,在High Performance MySQL一書中專門有過敘述,名為Avoiding Multiple Range Conditions,在復(fù)合索引里,僅僅只能保存一個range類型的查詢字段,并且要放到復(fù)合索引的末尾,否則,range類型查詢字段后面的索引無效。詳細的介紹大家可以自己查閱。從這個意義上來說,此時的category_id, comments, views復(fù)合索引的效果不會比category_id, comments復(fù)合索引的效果好。

            文件排序是否會引起性能問題要視數(shù)據(jù)分布情況而定。這里有一個案例可供參考:Using index for ORDER BY vs restricting number of rows.

            多數(shù)情況下應(yīng)該避免出現(xiàn)它。此時可以這樣設(shè)置索引:

            ALTER TABLE `article` ADD INDEX y ( `category_id` , `views` ) ;

            這時explain部分結(jié)果如下:

            type: range
            key: x
            Extra: Using where; Using filesort


            很奇怪,系統(tǒng)無視我們剛建立的y索引,還使用x索引。導(dǎo)致仍然存在文件排序。

            如果你也出現(xiàn)了類似的情況,可以使用強制索引:

            EXPLAIN SELECT author_id
            FROM `article`
            FORCE INDEX ( y )
            WHERE category_id = 1
            AND comments > 1
            ORDER BY views DESC
            LIMIT 1


            這時explain部分結(jié)果如下:

            type: ref
            key: y
            Extra: Using where

            也可以刪除x索引,那樣系統(tǒng)會自動使用y索引(有時候MySQL比較傻,所以你得會使用FORCE INDEX)。

            后記:Explain的type顯示的是訪問類型,是較為重要的一個指標(biāo),結(jié)果值從好到壞依次是:

            system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

            一般來說,得保證查詢至少達到range級別,最好能達到ref,否則就可能會出現(xiàn)性能問題。

            Explain的Extra信息也相當(dāng)重要,如果此信息顯示Using filesort或者Using temporary的話,噩夢即將開始,不過也不盡然,比如說在一個WHERE ... ORDER BY ... 類型的查詢里,很多時候我們無法創(chuàng)建一個兼顧WHERE和ORDER BY的索引,此時如果按照WHERE來確定索引,那么在ORDER BY時,就必然會引起Using filesort,文件排序是好是壞需要仔細判斷,說白了就是看是先過濾再排序劃算,還是先排序再過濾劃算,正確答案取決與數(shù)據(jù)分布的情況,具體的情況可以參考Using index for ORDER BY vs restricting number of rows

            Explain具體含義參見此鏈接:http://dev.mysql.com/doc/refman/5.1/en/using-explain.html


            posted on 2011-09-19 14:10 漂漂 閱讀(785) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久久久久亚洲精品不卡 | 欧美777精品久久久久网| 狠狠88综合久久久久综合网| 国产国产成人精品久久| 久久久久亚洲精品中文字幕| 天天爽天天狠久久久综合麻豆| 久久国产精品77777| 最新久久免费视频| 97久久久精品综合88久久| 欧美一级久久久久久久大| 91精品国产高清久久久久久io| 久久久99精品成人片中文字幕| 日韩精品久久久久久久电影蜜臀| 久久国产香蕉视频| 99精品国产在热久久无毒不卡| 久久精品国产亚洲Aⅴ蜜臀色欲| 久久精品人人槡人妻人人玩AV| 日本欧美国产精品第一页久久| 久久久久中文字幕| 韩国免费A级毛片久久| 欧美一区二区久久精品| 久久久精品久久久久久| 日本免费久久久久久久网站 | 99久久超碰中文字幕伊人| 亚洲国产精品无码久久青草| 亚洲国产成人久久综合一| 久久精品麻豆日日躁夜夜躁| 国产精品99久久久精品无码| 女同久久| 久久这里都是精品| 婷婷国产天堂久久综合五月| 一级a性色生活片久久无少妇一级婬片免费放 | 国产精品伦理久久久久久| 国产成人综合久久综合| 久久久久亚洲av无码专区喷水| 亚洲女久久久噜噜噜熟女| 色婷婷综合久久久中文字幕| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久夜色撩人精品国产小说| 久久久精品久久久久久| 色天使久久综合网天天|