<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 28,  comments - 15,  trackbacks - 0

    3.關(guān)于索引:

         3.1索引可以改善查詢,但會(huì)減慢更新,索引不是越多越好,最好不超過字段數(shù)的20%(在數(shù)據(jù)增、刪、改比較頻繁的表中,索引數(shù)量不應(yīng)超過5個(gè)。

         3.2離散程度越小,不適合加索引,例如:不要給性別建索引

            test.status取值范圍:0-9,在status列建索引

     

            mysql> select sql_no_cache * from test where status = 3 order by id limit 80000, 2;

            +--------+----------------+---------------------+------------+--------+

            | id     | time1          | time2               | time3      | status |

            +--------+----------------+---------------------+------------+--------+

            | 795783 | 20110825150959 | 2011-08-25 15:09:00 | 1314256140 |      3 |

            | 795789 | 20120829052359 | 2012-08-29 05:23:00 | 1346188980 |      3 |

            +--------+----------------+---------------------+------------+--------+

            2 rows in set (1.26 sec)

     

            刪除status索引后

            mysql> select sql_no_cache * from test where status = 3 order by id limit 80000, 2;

            +--------+----------------+---------------------+------------+--------+

            | id     | time1          | time2               | time3      | status |

            +--------+----------------+---------------------+------------+--------+

            | 795783 | 20110825150959 | 2011-08-25 15:09:00 | 1314256140 |      3 |

            | 795789 | 20120829052359 | 2012-08-29 05:23:00 | 1346188980 |      3 |

            +--------+----------------+---------------------+------------+--------+

            2 rows in set (0.37 sec)

     

         3.3.避免在空值(Null)很多的字段上建立索引,大量空值會(huì)降低索引效率

         3.4.避免在數(shù)據(jù)值分布不均的字段上建立索引,個(gè)別數(shù)據(jù)值占總數(shù)據(jù)量的百分率明顯比其它數(shù)據(jù)值占總數(shù)據(jù)量的百分率高,表明該字段數(shù)據(jù)值分布不均,容易引起數(shù)據(jù)庫選擇錯(cuò)誤索引,生成錯(cuò)誤的查詢執(zhí)行計(jì)劃。

         3.5.在數(shù)據(jù)量較少且訪問頻率不高的情況下,如只有一百行記錄以下的表不需要建立索引。因?yàn)樵跀?shù)據(jù)量少的情況下,使用全表掃描效果比走索引更好。

         3.6.字符字段必須建前綴索引

             單字母區(qū)分度:26

             4個(gè)字母區(qū)分度:26*26*26*26=456976

             6個(gè)字母區(qū)分度:26*26*26*26*26*26=308915776

             CREATE TABLE `test1` (

               `id` int(11) NOT NULL AUTO_INCREMENT,

               `a` char(20) NOT NULL DEFAULT '',

               `b` varchar(14) NOT NULL DEFAULT '00000000000000',

               `c` varchar(14) DEFAULT '00000000000000',

               PRIMARY KEY (`id`),

               KEY `a` (`a`(6))

             ) ENGINE=MyISAM AUTO_INCREMENT=12534199 DEFAULT CHARSET=gbk;

     

             mysql> select sql_no_cache count(*) from test1;

             +----------+

             | count(*) |

             +----------+

             | 12534198 |

             +----------+

             1 row in set (0.00 sec)

             mysql> select sql_no_cache count(*) from test1 where a = 'tR6cDjx0frXx45yURG1m';

             +----------+

             | count(*) |

             +----------+

             |        1 |

             +----------+

             1 row in set (0.00 sec)

     

         3.7.不在索引列做運(yùn)算,盡量不用外鍵(InnoDB)

         3.8.唯一索引:在建立索引的字段所有數(shù)值都具有唯一性特點(diǎn)的情況下,建立唯一索引(unique index)代替普通索引,唯一索引(unique index)查詢效率比普通索引查詢效率更高,可以大幅提升查詢速度。

     

    4.組合索引

         4.1.避免建立兩個(gè)或以上功能相同索引。例如已經(jīng)建立字段A、B兩個(gè)字段的索引,應(yīng)該避免再建立字段A的單獨(dú)索引。兩個(gè)索引之間,對(duì)相同的查詢都會(huì)起到相同的作用。建立兩個(gè)功能相同的索引,反而會(huì)容易引起數(shù)據(jù)庫產(chǎn)生錯(cuò)誤的查詢計(jì)劃,降低查詢效率。

     

         4.2.選擇正確的組合索引字段順序,最常用的查詢字段和選擇性、區(qū)分度較高的字段,應(yīng)該作為索引的前導(dǎo)字段使用。

             假設(shè)存在組合索引it1c1c2(c1,c2),查詢語句select * from t1 where c1=1 and c2=2能夠使用該索引。查詢語句select * from t1 where c1=1也能夠使用該索引。但是,查詢語句select * from t1 where c2=2不能夠使用該索引,因?yàn)闆]有組合索引的引導(dǎo)列,即,要想使用c2列進(jìn)行查找,必需出現(xiàn)c1等于某值。

     

         4.3.合適的字段數(shù),組合索引的字段數(shù)不適宜較多,較多的組合索引字段數(shù)會(huì)降低索引查詢效率,組合索引字段數(shù)應(yīng)不多于3個(gè),如業(yè)務(wù)特點(diǎn)需要建立多字段的組合主鍵例外。

        

         關(guān)于一個(gè)B-Tree索引的例子:

            假設(shè)有如下一個(gè)表:

            CREATE TABLE People (

               last_name varchar(50)    not null,

               first_name varchar(50)    not null,

               dob        date           not null,

               gender     enum('m', 'f') not null,

               key(last_name, first_name, dob)

            );

            其索引包含表中每一行的last_name、first_name和dob列。其結(jié)構(gòu)大致如下:


     

            索引存儲(chǔ)的值按索引列中的順序排列。可以利用B-Tree索引進(jìn)行全關(guān)鍵字、關(guān)鍵字范圍和關(guān)鍵字前綴查詢,當(dāng)然,如果想使用索引,你必須保證按索引的最左邊前綴(leftmost prefix of the index)來進(jìn)行查詢。

            (1)匹配全值(Match the full value):對(duì)索引中的所有列都指定具體的值。例如,上圖中索引可以幫助你查找出生于1960-01-01的Cuba Allen。

            (2)匹配最左前綴(Match a leftmost prefix):你可以利用索引查找last name為Allen的人,僅僅使用索引中的第1列。

            (3)匹配列前綴(Match a column prefix):例如,你可以利用索引查找last name以J開始的人,這僅僅使用索引中的第1列。

            (4)匹配值的范圍查詢(Match a range of values):可以利用索引查找last name在Allen和Barrymore之間的人,僅僅使用索引中第1列。

            (5)匹配部分精確而其它部分進(jìn)行范圍匹配(Match one part exactly and match a range on another part):可以利用索引查找last name為Allen,而first name以字母K開始的人。

            (6)僅對(duì)索引進(jìn)行查詢(Index-only queries):如果查詢的列都位于索引中,則不需要讀取元組的值。

            由于B-樹中的節(jié)點(diǎn)都是順序存儲(chǔ)的,所以可以利用索引進(jìn)行查找(找某些值),也可以對(duì)查詢結(jié)果進(jìn)行ORDER BY。當(dāng)然,使用B-tree索引有以下一些限制:

            (1) 查詢必須從索引的最左邊的列開始。關(guān)于這點(diǎn)已經(jīng)提了很多遍了。例如你不能利用索引查找在某一天出生的人。

            (2) 不能跳過某一索引列。例如,你不能利用索引查找last name為Smith且出生于某一天的人。

            (3) 存儲(chǔ)引擎不能使用索引中范圍條件右邊的列。例如,如果你的查詢語句為WHERE last_name="Smith" AND first_name LIKE 'J%' AND dob='1976-12-23',則該查詢只會(huì)使用索引中的前兩列,因?yàn)長IKE是范圍查詢。

        

         另一個(gè)例子:

            CREATE TABLE `friends` (

             `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

              `uid` bigint(20) unsigned NOT NULL DEFAULT '0',

              `fuid` bigint(20) unsigned NOT NULL DEFAULT '0',

              `fname` varchar(50) NOT NULL DEFAULT '',

              `fpicture` varchar(150) NOT NULL DEFAULT '',

              `fsex` tinyint(1) NOT NULL DEFAULT '0',

              `status` tinyint(1) NOT NULL DEFAULT '0',

              PRIMARY KEY (`id`),

              KEY `uid_fuid` (`uid`,`fuid`)

            ) ENGINE=MyISAM DEFAULT CHARSET=gbk;

     

     

     

     下一個(gè)



    5.覆蓋索引(Covering Indexes)

         如果索引包含滿足查詢的所有數(shù)據(jù),就稱為覆蓋索引。覆蓋索引是一種非常強(qiáng)大的工具,能大大提高查詢性能。只需要讀取索引而不用讀取數(shù)據(jù)有以下一些優(yōu)點(diǎn):

         (1)索引項(xiàng)通常比記錄要小,所以MySQL訪問更少的數(shù)據(jù);

         (2)索引都按值的大小順序存儲(chǔ),相對(duì)于隨機(jī)訪問記錄,需要更少的I/O;

         (3)大多數(shù)據(jù)引擎能更好的緩存索引。比如MyISAM只緩存索引。

         (4)覆蓋索引對(duì)于InnoDB表尤其有用,因?yàn)镮nnoDB使用聚集索引組織數(shù)據(jù),如果二級(jí)索引中包含查詢所需的數(shù)據(jù),就不再需要在聚集索引中查找了。

         注意:覆蓋索引不能是任何索引,只有B-TREE索引存儲(chǔ)相應(yīng)的值。而且不同的存儲(chǔ)引擎實(shí)現(xiàn)覆蓋索引的方式都不同,并不是所有存儲(chǔ)引擎都支持覆蓋索引(Memory和Falcon就不支持)。

         對(duì)于索引覆蓋查詢(index-covered query),使用EXPLAIN時(shí),可以在Extra一列中看到“Using index”

     

            CREATE TABLE `friends` (

              `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

              `uid` bigint(20) unsigned NOT NULL DEFAULT '0',

              `fuid` bigint(20) unsigned NOT NULL DEFAULT '0',

              `fname` varchar(50) NOT NULL DEFAULT '',

              `fpicture` varchar(150) NOT NULL DEFAULT '',

              `fsex` tinyint(1) NOT NULL DEFAULT '0',

              `status` tinyint(1) NOT NULL DEFAULT '0',

              PRIMARY KEY (`id`),

              KEY `uid_fuid` (`uid`,`fuid`)

            ) ENGINE=MyISAM DEFAULT CHARSET=gbk;

     

     

     

    6.排序

         MySQL中,有兩種方式生成有序結(jié)果集:

         a. filesort            糟糕

         b. Index排序            

     

    什么時(shí)候使用Index排序?

        當(dāng)索引的順序與ORDER BY中的列順序相同且所有的列是同一方向(全部升序或者全部降序)時(shí),可以使用索引來排序。其它情況都會(huì)使用filesort。

     

    什么時(shí)候使用filesort?

         當(dāng)MySQL不能使用Index排序時(shí),就會(huì)利用自己的排序算法(快速排序算法)在內(nèi)存(sort buffer)中對(duì)數(shù)據(jù)進(jìn)行排序,如果內(nèi)存裝載不下,它會(huì)將磁盤上的數(shù)據(jù)進(jìn)行分塊,再對(duì)各個(gè)數(shù)據(jù)塊進(jìn)行排序,然后將各個(gè)塊合并成有序的結(jié)果集(實(shí)際上就是外排序)。

         當(dāng)對(duì)連接操作進(jìn)行排序時(shí),如果ORDER BY僅僅引用第一個(gè)表的列,MySQL對(duì)該表進(jìn)行filesort操作,然后進(jìn)行連接處理,此時(shí),EXPLAIN輸出“Using filesort”;

         否則,MySQL必須將查詢的結(jié)果集生成一個(gè)臨時(shí)表,在連接完成之后進(jìn)行filesort操作,此時(shí),EXPLAIN輸出“Using temporary;Using filesort”。

     

         通過索引優(yōu)化來實(shí)現(xiàn)MySQL的ORDER BY語句優(yōu)化例子:

     

         1、ORDER BY的索引優(yōu)化。如果一個(gè)SQL語句形如:

            SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort];

            在[sort]這個(gè)欄位上建立索引就可以實(shí)現(xiàn)利用索引進(jìn)行order by 優(yōu)化。

     

         2、WHERE + ORDER BY的索引優(yōu)化,形如:

            SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [value] ORDER BY [sort];

            建立一個(gè)聯(lián)合索引(columnX,sort)來實(shí)現(xiàn)order by 優(yōu)化。

           

            注意:如果columnX對(duì)應(yīng)多個(gè)值,如下面語句就無法利用索引來實(shí)現(xiàn)order by的優(yōu)化

            SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] IN ([value1],[value2],…) ORDER BY[sort];

     

         3、WHERE+ 多個(gè)字段ORDER BY

            SELECT * FROM [table] WHERE uid=1 ORDER x,y LIMIT 0,10;

            建立索引(uid,x,y)實(shí)現(xiàn)order by的優(yōu)化,比建立(x,y,uid)索引效果要好得多。

            

     

         MySQL Order By不能使用索引來優(yōu)化排序的情況:

     

         1、對(duì)不同的索引鍵做 ORDER BY :(key1,key2分別建立索引)

            SELECT * FROM t1 ORDER BY key1, key2;

     

     

         2、用于where語句的索引和ORDER BY 的不是同一個(gè):(key1,key2分別建立索引)

            SELECT * FROM t1 WHERE key2=constant ORDER BY key1;

     

     

     

         3、同時(shí)使用了 ASC 和 DESC:(key_part1,key_part2建立聯(lián)合索引),通過where語句將order by中索引列轉(zhuǎn)為常量,則除外

            SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

     

     

         4、如果在WHERE或ORDER BY的欄位上應(yīng)用表達(dá)式(函數(shù))時(shí),則無法利用索引來實(shí)現(xiàn)order by的優(yōu)化

            SELECT * FROM t1 ORDER BY YEAR(logindate) LIMIT 0,10;

     

     

     

         5、檢查的行數(shù)過多,且沒有使用覆蓋索引

           

        

         6、where語句中使用了條件查詢

     

     

     

    7.關(guān)于group by或distinct

        7.1.盡量只對(duì)存在索引的字段進(jìn)行g(shù)roup by或distinct。當(dāng)group by 不能使用index 時(shí)mysql有兩種處理方法:臨時(shí)表和filesort。

         7.2.在group by 語句中mysql會(huì)自動(dòng)order,如果不需要可使用order by null來禁止自動(dòng)的order。

     

     

    8.關(guān)于索引失效

         8.1.避免對(duì)索引字段計(jì)算

     

         8.2.避免使用索引列值是否可為空的索引,如果索引列值可以是空值,在SQL語句中那些要返回NULL值的操作,將不會(huì)用到索引。

     

         8.3.相同的索引列不能互相比較,這將會(huì)啟用全表掃描,如tab1上存在索引idx_col1_col2(col1,col2),其中col1和col2都是int型。則查詢語句SELECT * FROM tab1 WHERE col1>col2;是不會(huì)使用索引的。

     

         8.4.避免使用存在潛在的數(shù)據(jù)類型轉(zhuǎn)換的索引。潛在的數(shù)據(jù)轉(zhuǎn)換,查詢條件中是指由于等式兩端的數(shù)據(jù)類型不一致。例如索引字段使用的是數(shù)字類型,而條件等式的另一端數(shù)據(jù)類型是字符類型,數(shù)據(jù)庫將會(huì)對(duì)其中一端進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,數(shù)據(jù)類型的轉(zhuǎn)換會(huì)讓索引的作用失效,令數(shù)據(jù)庫選擇其他的較為低效率的訪問路徑。




     

         8.5.使用索引列作為條件進(jìn)行查詢時(shí),需要避免使用<>或者!=等判斷條件。如確實(shí)業(yè)務(wù)需要,使用到不等于符號(hào),需要在重新評(píng)估索引建立,避免在此字段上建立索引,改由查詢條件中其他索引字段代替。

          a)盡量避免負(fù)向查詢:NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE,避免%前模糊查詢

          b)WHERE條件中的范圍查詢(IN、BETWEEN、<、<=、>、>=)會(huì)導(dǎo)致后面的條件使用不了索引。

     

         8.6.使用索引列作為條件進(jìn)行范圍查詢時(shí),應(yīng)該避免較大范圍取值。

     

     

     

    posted on 2014-05-08 19:48 zhangxl 閱讀(2033) 評(píng)論(4)  編輯  收藏 所屬分類: DB


    FeedBack:
    # re: Mysql索引相關(guān)知識(shí)分享
    2014-05-09 06:21 | 金利鎖業(yè)
    支持博主分享  回復(fù)  更多評(píng)論
      
    # re: Mysql索引相關(guān)知識(shí)分享
    2014-05-09 07:23 | 金利鎖業(yè)
    支持博主分享.。。。。。。。。。。。。。  回復(fù)  更多評(píng)論
      
    # re: Mysql索引相關(guān)知識(shí)分享
    2014-05-09 09:55 | zhangxl
    @金利鎖業(yè)
    這個(gè)公司內(nèi)部分享,個(gè)人覺得都大多數(shù)開發(fā)者來說具有參考價(jià)值  回復(fù)  更多評(píng)論
      
    # re: Mysql索引相關(guān)知識(shí)分享
    2014-05-09 17:06 | 任務(wù)大廳
    很有價(jià)值的分享,值得學(xué)習(xí)  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2014年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(1)

    隨筆分類(17)

    隨筆檔案(28)

    文章分類(30)

    文章檔案(30)

    相冊(cè)

    收藏夾(2)

    hibernate

    java基礎(chǔ)

    mysql

    xml

    關(guān)注

    壓力測試

    算法

    最新隨筆

    搜索

    •  

    積分與排名

    • 積分 - 96306
    • 排名 - 601

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 国产国拍精品亚洲AV片| 我的小后妈韩剧在线看免费高清版| 色吊丝免费观看网站| 亚洲老熟女五十路老熟女bbw| 亚洲一区在线视频| 亚洲人成高清在线播放| 亚洲AV无码乱码麻豆精品国产| 亚洲日本va午夜中文字幕一区| 亚洲国产综合专区电影在线| 亚洲最大的成网4438| 久久久久亚洲AV片无码下载蜜桃 | 久久久久久毛片免费播放| 最近免费mv在线观看动漫| 污污网站免费观看| 88av免费观看入口在线| 99久久这里只精品国产免费 | 日韩一级片免费观看| 永久免费精品影视网站| 好湿好大好紧好爽免费视频| 天黑黑影院在线观看视频高清免费| 精品国产麻豆免费人成网站| 99在线观看视频免费| av免费不卡国产观看| 国产精品成人免费综合| 久久亚洲中文字幕精品一区| 亚洲成在人线av| 亚洲国产美女视频| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲今日精彩视频| 亚洲成aⅴ人片在线观| 亚洲中文字幕无码亚洲成A人片 | 中文字幕亚洲色图| 亚洲综合欧美色五月俺也去| 阿v免费在线观看| 精品国产麻豆免费人成网站| 免费不卡视频一卡二卡| 免费一级一片一毛片| 亚洲AV午夜成人片| 久久精品国产亚洲AV蜜臀色欲| 亚洲欧美在线x视频| 永久免费AV无码网站国产|