亚洲狠狠久久综合一区二区三区

<progress id="73rr5"></progress>
<tbody id="73rr5"><pre id="73rr5"></pre></tbody>

    <tbody id="73rr5"></tbody><dd id="73rr5"><track id="73rr5"></track></dd>
    PHP面試指南2020-MySQL索引- 詳解

    成人自考/成人高考/教師資格證/會計從業資格證/建造師/造價師,一個小程序就夠啦。

    什么是索引

    索引是存儲引擎用于快速找到記錄的一種數據結構.

    理解索引

    一個常見的例子就是書的目錄。我們都已經養成了看目錄的習慣,拿到一本書時,我們首先會先去查看他的目錄,并且當我們要查找某個內容時,我們會在目錄中查找,然后找到該片段對應的頁碼,再根據相應的頁碼去書中查找。如果沒有索引(目錄)的話,我們就只能一頁一頁的去查找了。

    在MySQL中,假設我們有一張如下記錄的表:

    idnameage
    1huyan10
    2huiui18
    3lumingfei20
    4chuzihang15
    5nono21

    如果我們希望查找到年齡為15的人的名字,在沒有索引的情況下我們只能遍歷所有的數據去做逐一的對比,那么時間復雜度是O(n).

    而如果我們在插入數據的過程中, 額外維護一個數組,將age字段有序的存儲.得到如下數組.

    [10,15,18,20,21]
     |  |  |  |  |[x1,x4,x2,x3,x5]

    下面的x是模擬數據再磁盤上的存儲位置,這個時候如果我們需要查找15歲的人的名字,我們可以對蓋數組進行二分查找,眾所周知,二分查找的時間復雜度為O(logn),查找到之后再根據具體的位置去獲取真正的數據。

    PS:MySQL中的索引不是使用的數組,而是使用的B+樹(后面講),這里用數組舉例只是因為比較好理解.

    索引分類

    索引創建

    ALTER TABLE `table_name` ADD INDEX index_name (`column`); #普通索引
    ALTER TABLE `table_name` ADD UNIQUE (`column`); #唯一索引
    ALTER TABLE `table_name` ADD PRIMARY KEY (`column`); #主鍵索引
    ALTER TABLE `table_name` ADD FULLTEXT (`column`); #全文索引
    ALTER TABLE `table_name` ADD INDEX index_name (`column1`, `column2`, `column3`); #組合索引

    索引能為我們帶來什么

    • 減少查詢需要掃描的數據量(加快了查詢速度)

    • 減少服務器的排序操作和創建臨時表的操作(加快了groupby和orderby等操作)

    • 將服務器的隨機IO變為順序IO(加快查詢速度).

    索引有哪些缺點呢

    • 索引占用磁盤或者內存空間

    • 減慢了插入更新操作的速度

    實際上,在一定數據范圍內(索引沒有超級多的情況下),建立索引帶來的開銷是遠遠小于它帶來的好處的,但是我們仍然要防止索引的濫用.

    聚族索引與非聚族索引的區別

    • 按物理存儲分類:聚簇索引(clustered index)、非聚簇索引(non-clustered index)

    • 聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針

    前綴索引和索引選擇性

    如果希望給一個很長的字符串上添加索引,那么可以考慮使用前綴索引。

    在正式介紹前綴索引之前,我們先大概考慮一下索引的工作步驟,數據庫使用索引進行查找的時候,一般是如下幾步:

    1. 在索引的B+樹上找到對應的值,比如找到學校名稱為卡塞爾學院的一條記錄,并且拿到這條數據在磁盤上的地址。

    2. 根據地址去磁盤上查找,拿到該條數據所有的值。

    那么假如在所有的學校名稱的值中,卡塞爾就可以唯一的標識這條數據,那么用卡塞爾來做索引是否可以達到和卡塞爾學院做索引相同的效果?

    答案是肯定的,而使用卡塞爾的話,是可以減少索引的大小到原來的60%的。這就是前綴索引的作用。

    前綴索引: 在對一個比較長的字符串進行索引時,可以僅索引開始的一部分字符,這樣可以大大的節約索引空間,從而提高索引效率.但是這樣也會降低索引的選擇性.

    索引的選擇性: 不重復的值/所有的值. 可以看出索引的選擇性為0-1,最高的就是該列唯一,沒有重復值.所以唯一索引的效率是比較好的.

    但是在一般情況下,較長的字符串的一些前綴的選擇性也是比較好的,這個我們可以算出來.使用下面的語句:

    select 
        count(distinct left(school_name,3))/count(*) as sch3, 
        count(distinct left(school_name,4))/count(*) as sch4,
        count(distinct left(school_name,5))/count(*) as sch5,
        count(distinct school_name)/count(*) as original
    from 
        user;

    其中查找到的original就是原本的選擇性,sch3,sch4,sch5分別是取該列的前3,4,5個字符作為索引的時候的選擇性.逐步增加這個數值,當選擇性與原來相差不大的時候,就是一個比較合適的前綴索引的長度.(一般情況下是這樣,但是也有例外,當數據極其不均勻時,這樣的前綴索引會在某個特殊的case上表現很差勁).

    找到合適的長度之后,就可以創建一個前綴索引了:alter table user add index sch_pre3(school(3))

    注意:前綴索引和覆蓋索引是很難一起使用的,我今天早上剛試過,對索引的優化進行到這一步之后無功而返,具體的原因在下面介紹完覆蓋索引之后解釋.

    聯合索引

    一般我們都是有對多個列進行索引的需求的,因為查詢的需求多種多樣.這個時候我們可以選擇建立多個獨立的索引或者建立一個聯合索引.大多數時候都是聯合索引更加合適一些.

    假設我們要執行這個語句:select * from user where school_name = '卡塞爾' and age > 20,我們在schoolage上分別建立兩個獨立的索引,那么我們預期這條查詢語句會命中兩個索引,但是使用explain命令查看會發現不一定.這是一個玄學的過程.個人沒有研究清楚.

    從理論上來講,MySQL在5.0之后的版本里面對支持合并索引,也就是同時使用兩個索引,但是MySQL的優化器不一定這樣認為,他可能會認為,查詢兩次B+樹的代價高于查詢一次索引之后去數據表進行過濾,因此會選擇只用一個索引.(我在自己的5張表上做了類似此case的測試,結果都是只使用了一個索引.)

    創建聯合索引的語法:alter table user add index school_age(school,age).

    使用聯合索引的時候,有一個非常重要的因素就是所有的索引列只可以進行最左前綴匹配,例如上面的school_age聯合索引,當僅使用age作為查詢條件的時候是不能使用的,也就是說select * from user where age =20是不能命中上面的聯合索引的.

    在不考慮任何查詢的情況下,我們應該講選擇性高的列放在聯合索引的前面,但是實際上我們更多的是通過查詢來反推索引,以使某個固定的查詢可以盡可能的命中索引以提高查詢速度.畢竟我們建立索引的目的也是為了加快查詢的速度.

    因此聯合索引的優化更多的是根據某個或者某些語句來優化的,不具備一個通用的法則.

    最左前綴索引的原理

    當數據列有序的時候,mysql可以使用索引,那么假設我們建立了school_age索引,示例數據如下:

    schoolage
    a12
    b12
    b14
    b15
    c1

    在這份數據中,school字段是完全有序的,索引school可以使用索引.

    而從全表來看,age字段不是有序的,因此無法直接使用索引,那么觀察一下數據表,在什么時候age有序呢?在school進行定值匹配的時候,例如當school=b的時候,對于這三條數據而言,age是有序的,因此可以使用age索引.這就是最左前綴的原理.

    此外,最左前綴索引只能使用一個范圍查詢,例如select * from user where school > a,select * from user where school = a and age > 12,都是可以命中索引的,但是select * from user where school > a and age > 12中,僅school可以命中索引,這也可以從上面得出結論.因為當school是范圍匹配的時候,mysql無法確認age字段是否嚴格有序,比如 school的范圍匹配命中了b,c的四條數據,那么age就不是有序的.無法使用后續的索引.

    聚簇索引

    聚簇索引不是一種索引類型,而是一種存儲數據的方式.Innodb的聚簇索引是在同一個數據結構中保存了索引和數據.

    因為數據真正的數據只能有一種排序方式,所以一個表上只能有一個聚簇索引.Innodb使用主鍵來進行聚簇索引,沒有主鍵的話就會選擇一個唯一的非空索引,如果還還沒有,innodb會選擇生成一個隱式的主鍵來進行聚簇索引.為什么innodb這么執著的需要搞一個聚簇索引呢,因為一個數據表中的數據總得有且只有一種排序方式來存儲在磁盤上,因此這是必須的.

    這也是innodb推薦我們使用自增主鍵的原因,因為自增主鍵自增且連續,在插入的時候只需要不斷的在數據后面追加即可.設想一下使用UUID來作為主鍵,那么每一次的插入操作,都需要找到當前主鍵在已排序的主鍵中的位置,然后插入,并且要移動該主鍵后的數據,以使得數據和主鍵保持相同的順序,這無疑是代價非常高的.

    也是因為這個原因,在其他索引的葉子節點中,存儲的”數據”其實不是該數據的真實物理地址,而是該數據的主鍵,查找到主鍵之后,再根據主鍵進行一次索引,拿到數據.

    聚簇索引和非聚簇索引的區別可以用一個簡單的例子來說明:

    當我們拿到一本書的時候,目錄就是主鍵,是一個聚簇索引,因為在目錄中連續的內容,在正文中也是連續的,當我們想要查看迎著陽光盛大逃亡章節,只需要在目錄中找到它對應的頁面,比如459,然后去對應的頁碼查看正文即可.

    而非聚簇索引呢,則類似于書后面的附錄專有名詞索引一樣(二級普通索引),當你查找邦達列夫的時候,附錄會告訴你,這個名詞出現在了迎著陽光盛大逃亡一節,然后你需要去目錄(主鍵索引)中再次查找到對應的頁碼.

    覆蓋索引

    當一個索引包含(或者說是覆蓋)需要查詢的所有字段的值時,我們稱之為覆蓋索引.

    設想有如下的查詢語句:

    select 
      school_name,age
    from  
      user
    where 
      school_name = '金色鶯尾花學院'

    這個語句根據學校名稱來查詢數據行的學校名稱和年齡,從上面的數據查詢的步驟我們可以知道,當在索引中找到要求的值的時候,還需要根據主鍵去進行一次索引,以拿到全部的數據,然后從其中挑選出需要的列,返回.但是現在索引中已經包含了所有的需要返回的列,那么就不用進行回數據表查詢的操作了,此外索引的大小一般是遠遠小于真正的數據大小的,覆蓋索引可以極大的減少從磁盤加載數據的數量.

    為什么前綴索引和覆蓋索引無法一起使用?

    因為前綴索引的目的是用前綴來代表真正的值,他們在選擇性上幾乎沒有區別,但是MySQL仍然無法判斷真正的數據是什么,比如阿里巴巴阿里媽媽在前綴為2的時候是一樣的,但是為了確保你查詢阿里巴巴的時候不會出現阿里媽媽的內容,是需要回到數據表拿到數據再次進行一個精準匹配來進行過濾的.

    因此,覆蓋索引無法和列前綴索引一起使用。

    刪除掉冗余和重復的索引

    有一些索引是從未在查詢中使用過,卻白白增加數據插入時開銷的,對于這種索引我們應該及時的進行刪除.

    比如在主鍵上再建立一個普通索引,無疑是毫無作用的.

    還比如在有聯合索引school_age的情況下,再建立一個school的獨立索引,因為索引的最左前綴匹配原則,school_age是完全可以命中對school的單獨查詢的,因此后者可以刪掉.

    如何查看索引的一些相關信息

    索引信息

    在mysql中可以使用show index from table_name來查看某個表上的索引,它將會有如下的輸出:

    或者使用show create table table_name來查看建表語句,其中包含創建索引的語句.

    索引大小

    在5.0以后的版本中,我們可以通過查看information_schema.TABLES表中的數據來獲取更加詳細的數據.

    該表各字段的含義如下表:

    字段含義

    Table_catalog數據表登記目錄

    Table_schema數據表所屬的數據庫名

    Table_name表名稱

    Table_type表類型[system viewbase table]
    Engine使用的數據庫引擎[MyISAMCSVInnoDB]
    Version版本,默認值10

    Row_format行格式[CompactDynamicFixed]
    Table_rows表里所存多少行數據

    Avg_row_length平均行長度

    Data_length數據長度

    Max_data_length最大數據長度

    Index_length索引長度

    Data_free空間碎片

    Auto_increment做自增主鍵的自動增量當前值

    Create_time表的創建時間

    Update_time表的更新時間

    Check_time表的檢查時間

    Table_collation表的字符校驗編碼集

    Checksum校驗和

    Create_options創建選項

    Table_comment表的注釋、備注

    我們可以通過一些查詢語句來獲取詳細的信息,比如:

    // 查看當前MySQL服務器所有索引的大小(以MB為單位,默認是字節)SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM TABLES// 查看某一個庫的所有大小SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM TABLES  WHERE table_schema = 'XXX';// 查看某一個表的索引大小SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM TABLES  WHERE table_schema = 'yyyy' and table_name = "xxxxx";  // 匯總查看一個庫中的數據大小及索引大小SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name', CONCAT(ROUND(table_rows/1000000,4),'M') AS 'Number of Rows', CONCAT(ROUND(data_length/(1024*1024*1024),4),'G') AS 'Data Size', CONCAT(ROUND(index_length/(1024*1024*1024),4),'G') AS 'Index Size', CONCAT(ROUND((data_length+index_length)/(1024*1024*1024),4),'G') AS'Total'FROM information_schema.TABLES WHERE table_schema LIKE 'xxxxx';

    對tables表的數據的所有查看方式都是可以的,其中還包含了一些表格本身的數據信息,但是因為和本文的主題不符合,這里就不舉例子了.

    注意:上面的表格是有緩存的,當更新數據庫索引之后,最好執行analyze table xxxx,然后再進行查看.MySQL會在表格數據發生較大的變化時才更新此表(大小變化超過1/16或者插入20億行).

    索引碎片

    在索引的創建刪除過程中,不可避免的會產品索引碎片,當然還有數據碎片,我們可以通過執行optimize table xxx來重新整理索引及數據,對于不支持此命令的存儲引擎來說,可以通過一條無意義的alter語句來觸發整理,比如:將表的存儲引擎更換為當前的引擎,alter table xxxx engine=innodb.

    btree索引和hash索引的區別

    Innodb和MyISAM默認的索引是Btree索引。

    Hash 索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位,不像B-Tree 索引需要從根節點到枝節點,最后才能訪問到頁節點這樣多次的IO訪問,所以 Hash 索引的查詢效率要遠高于 B-Tree 索引。

    可能很多人又有疑問了,既然 Hash 索引的效率要比 B-Tree 高很多,為什么大家不都用 Hash 索引而還要使用 B-Tree 索引呢?任何事物都是有兩面性的,Hash 索引也一樣,雖然 Hash 索引效率高,

    Hash 索引本身由于其特殊性,也帶來了很多限制和弊端

    (1)Hash 索引僅僅能滿足"=","IN"和"<=>"查詢,不能使用范圍查詢。

    由于 Hash 索引比較的是進行 Hash 運算之后的 Hash 值,所以它只能用于等值的過濾,不能用于基于范圍的過濾,因為經過相應的 Hash 算法處理之后的 Hash 值的大小關系,并不能保證和Hash運算前完全一樣。

    (2)Hash 索引無法被用來避免數據的排序操作。

    由于 Hash 索引中存放的是經過 Hash 計算之后的 Hash 值,而且Hash值的大小關系并不一定和 Hash 運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算;

    (3)Hash 索引不能利用部分索引鍵查詢。

    對于組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合并后再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。

    (4)Hash 索引在任何時候都不能避免表掃描。

    前面已經知道,Hash 索引是將索引鍵通過 Hash 運算之后,將 Hash運算結果的 Hash 值和所對應的行指針信息存放于一個 Hash 表中,由于不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數據的記錄條數,也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數據進行相應的比較,并得到相應的結果。

    (5)Hash 索引遇到大量Hash值相等的情況后性能并不一定就會比B-Tree索引高。

    對于選擇性比較低的索引鍵,如果創建 Hash 索引,那么將會存在大量記錄指針信息存于同一個 Hash 值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數據的訪問,而造成整體性能低下

    mysql索引類型normal,unique,full text的區別

    normal:表示普通索引
    
    unique:表示唯一的,不允許重復的索引,如果該字段信息保證不會重復例如身份證號用作索引時,可設置為unique。
    
    full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很長一篇文章的時候,效果最好。用在比較短的文本,如果就一兩行字的,普通的 INDEX 也可以。

    索引本身的實現(數據結構)

    我們在線上遇到慢查詢的情況,一般第一個想到的優化方式就是給where語句后的字段加索引,雖然效果是立竿見影的,但這通常是懶人做法。一方面是因為索引并不是都會生效,可能出現加了索引,查詢依舊慢的問題,另一方面,索引會占用磁盤空間。

    但是,這并不妨礙我們在遇到慢查詢的時候,第一個想到的解決方案就是加索引,那么,為什么加了索引之后,就能優化慢查詢,提升查詢速度?

    其實,索引就是一種優化查詢的數據結構,MySQL中的索引就是用B+樹實現的。那么為什么MySQL會選擇B+樹作為索引的實現數據結構呢?它和哈希表、完全平衡二叉樹、B樹有什么不同?

    假設,我們現在有下面的user表:

    ① 哈希表

    我們知道,hashMap(1.7)底層就是通過哈希表來實現的,即,數組+鏈表的方式。
    哈希表的缺點有兩個: 一、hash沖突,二、只支持精確查詢,不支持范圍查詢,如果我們要某個年齡大于18的用戶,如下:

    select * from user where name = '關羽'; // 精確查找select * from user where name > '關羽'; // 范圍查找

    這種情況哈希表并不能實現,所以,哈希表不適合做MySQL的索引數據結構。

    ②完全平衡二叉樹

    平衡二叉樹的每個節點都包含下面四部分信息:

    1. 左指針,指向左子樹

    2. 鍵值

    3. 鍵值所對應的數據存儲地址

    4. 右指針,指向右子樹

    另外,二叉樹是有序的,簡而言之,就是左節點小于右節點,所以,平衡二叉樹是支持范圍查找的,但是,在精確查找的時候,會涉及到多次,比如,查劉備,需要查詢三次才能找到,比哈希表的精確查找要慢。

    ③ B樹

    可以看到,B樹在層級上比平衡二叉樹要少一層,即少一次磁盤IO,原因在于,B樹中的一個節點可以存儲多個元素。

    ④ B+樹

    B+樹的葉子節點和B樹是一樣的,只不過冗余了一分非葉子節點的數據

    B+樹比B樹要胖一些,原因在于B+樹中的非葉子節點會冗余一分在葉子節點中,并且葉子節點之間用指針相連。

    綜上,我們可以看出,有三種數據結構是適合做MySQL索引的數據結構的,平衡二叉樹、B樹、B+樹。這三種數據結構都支持精確查找和范圍查找,那么為什么MySQL卻選中了B+樹作為索引的數據結構呢?

    其實,索引也是存儲元素的,當我們的一個表中的數據越來越多時,對應的索引文件也會越來越大,這樣就不能把全部的索引文件放在內存,不得不將索引文件存儲在磁盤上,那么選用哪種數據結構,能夠提高磁盤的IO效率,就成了參考項。

    如果使用完全平衡二叉樹來查詢“張飛”,則需要四次IO,而使用B樹的話,只要三次就可以了,提升了磁盤IO效率,而B+樹和B樹的非葉子節點是一樣的,只不過是葉子節點冗余了一份非葉子節點的數據。所以,在精確查找上,B樹和B+樹是一樣的,而B+樹在范圍查找上優于B樹。

    MySQL為什么要選擇B+樹來作為索引的數據結構

    重點:B+樹能提高查詢效率,降低磁盤IO

    1、B+數是由B-數演變而來,所以B+數擁有B-數的所有特性
    2、B+樹的非葉子節點只保存關鍵字和子節點的地址,而葉子節點保留了當前路節點的所有節點的關鍵字、數據區和地址,所以要得到節點的數據就要到葉子節點上去獲取,所以我們每次對數據的檢索的時間都差不多,不像其他樹,非葉子節點也有保留數據區,這樣子當數據量龐大,當檢索第一個跟最后一個的索引時間就相差比較大
    2、B+樹是一顆多路平衡查找樹,由于它是多路的,所以它的高度比其他二叉樹都矮,樹的高度決定了檢索數據的時間復雜度
    計算機默認檢索的一頁是4k,而mysql對這個4k做了調整增加到16k,這個一頁是16k,假如這里保存的是一個id的索引樹,那id設置為int類型,一個int類型為4個字節,那這一頁可以保存的id的個數就可以這樣算((16* 1024)/4),所以索引的類型和字節數都決定了數據庫檢索數據的效率,所以該id樹的一個節點可以設置的路數就為((16*1024)/4)路,所以這一頁就可以保存這么多數據,一次加載到內存中就可以加載那么多,充分利用了計算機的IO讀取性能和空間局部性原理,極大降低了計算機IO的次數
    3、B+樹的葉子節點上保存一個指針,這個指針指向的是下一個葉子節點的指針,譬如第一路的葉子節點上數據有567這三個樹,而第二路有8910,則第一路的7有個指針會指向第二路的8,這樣做的好處是使數據自帶有順序性的特性,這個順序性在我們做一個范圍查詢時,性能就得到充分的發揮,這個指針也是B-樹跟B+樹的區別之一

    總而言之:

    B+樹是B-樹的變種(PLUS版)多路絕對平衡查找樹,他擁有B-樹的特點(優勢 ) 
    B+樹掃庫、表能力更強  
    B+樹的磁盤讀寫能力更強  
    B+樹的排序能力更強  
    B+樹的查詢效率更加穩定

    創建索引需要注意的點(原則)

    1、表的主鍵、外鍵必須有索引;
    2、數據量超過300的表應該有索引;
    3、經常與其他表進行連接的表,在連接字段上應該建立索引;
    4、經常出現在Where子句中的字段,特別是大表的字段,應該建立索引;
    5、索引應該建在選擇性高的字段上;
    6、索引應該建在小字段上,對于大的文本字段甚至超長字段,不要建索引;
    7、復合索引的建立需要進行仔細分析;盡量考慮用單字段索引代替:

    A、正確選擇復合索引中的主列字段,一般是選擇性較好的字段;
    B、復合索引的幾個字段是否經常同時以AND方式出現在Where子句中?單字段查詢是否極少甚至沒有?如果是,則可以建立復合索引;否則考慮單字段索引;
    C、如果復合索引中包含的字段經常單獨出現在Where子句中,則分解為多個單字段索引;
    D、如果復合索引所包含的字段超過3個,那么仔細考慮其必要性,考慮減少復合的字段;
    E、如果既有單字段索引,又有這幾個字段上的復合索引,一般可以刪除復合索引;

    8、頻繁進行數據更新的表,不要建立太多的索引,會早晨很多索引碎片;
    9、刪除無用的索引,避免對執行計劃造成負面影響;

    一般選擇在這樣的列上創建索引


    1. 在經常需要搜索查詢的列上創建索引,可以加快搜索的速度;

    2. 在作為主鍵的列上創建索引,強制該列的唯一性和組織表中數據的排列結構;

    3. 在經常用在連接的列上創建索引,這些列主要是一些外鍵,可以加快連接的速度;

    4. 在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的;

    5. 在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢 時間;

    6. 在經常使用在Where子句中的列上面創建索引,加快條件的判斷速度;

    7. 為經常出現在關鍵字order by、group by、distinct后面的字段,建立索引。

    一般不選擇具有這些特點的列上創建索引


    1. 對于那些在查詢中很少使用或者參考的列不應該創建索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,并不能提高查 詢速度。相反,由于增加了索引,反而降低了系統的維護速度和增大了空間需求;

    2. 不要在有大量相同取值的字段上,建立索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,并不能明顯加 快檢索速度;

    3. 對于那些定義為text, image和bit數據類型的列不應該增加索引。這是因為,這些列的數據量要么相當大,要么取值很少;

    4. 當修改性能遠遠大于檢索性能時,不應該創建索引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大于檢索性能時,不應該創建索引。

    創建索引需要注意的地方

    1. 限制表上的索引數目。對一個存在大量更新操作的表,所建索引的數目一般不要超過3個,最多不要超過5個。索引雖說提高了訪問速度,但太多索引會影響數據的更新操作。

    2. 避免在取值朝一個方向增長的字段(例如:日期類型的字段)上,建立索引;對復合索引,避免將這種類型的字段放置在最前面。由于字段的取值總是朝一個方向增長,新記錄總是存放在索引的最后一個葉頁中,從而不斷地引起該葉頁的訪問競爭、新葉頁的分配、中間分支頁的拆分。此外,如果所建索引是聚集索引,表中數據按照索引的排列順序存放,所有的插入操作都集中在最后一個數據頁上進行,從而引起插入“熱點”。

    3. 對復合索引,按照字段在查詢條件中出現的頻度建立索引。在復合索引中,記錄首先按照第一個字段排序。對于在第一個字段上取值相同的記錄,系統再按照第二個字段的取值排序,以此類推。因此只有復合索引的第一個字段出現在查詢條件中,該索引才可能被使用。因此將應用頻度高的字段,放置在復合索引的前面,會使系統最大可能地使用此索引,發揮索引的作用。

    4. 刪除不再使用,或者很少被使用的索引。表中的數據被大量更新,或者數據的使用方式被改變后,原有的一些索引可能不再被需要。數據庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。

    訪客
    郵箱
    網址

    Top 亚洲狠狠久久综合一区二区三区
    <progress id="73rr5"></progress>
    <tbody id="73rr5"><pre id="73rr5"></pre></tbody>

      <tbody id="73rr5"></tbody><dd id="73rr5"><track id="73rr5"></track></dd>