導航:首頁 > 數據處理 > 資料庫哪些列適合索引

資料庫哪些列適合索引

發布時間:2023-08-28 00:06:39

㈠ MySql索引之哪些情況適合創建索引

說明:不要以為唯一索引影響了 insert 速度,這個速度損耗可以忽略,但提高查找速度是明顯的。

某個欄位在SELECT語句的 WHERE 條件中經常被使用到,那麼就需要給這個欄位創建索引了。尤其是在

數據量大的情況下,創建普通索引就可以大幅提升數據查詢的效率。

比如student_info數據表(含100萬條數據),假設我們想要查詢 student_id=123110 的用戶信息。

索引就是讓數據按照某種順序進行存儲或檢索,因此當我們使用 GROUP BY 對數據進行分組查詢,或者

使用 ORDER BY 對數據進行排序的時候,就需要 對分組或者排序的欄位進行索引 。如果待排序的列有多

個,那麼可以在這些列上建立 組合索引 。

對數據按照某個條件進行查詢後再進行 UPDATE 或 DELETE 的操作,如果對 WHERE 欄位創建了索引,就

能大幅提升效率。原理是因為我們需要先根據 WHERE 條件列檢索出來這條記錄,然後再對它進行更新或

刪除。如果進行更新的時候,更新的欄位是非索引欄位,提升的效率會更明顯,這是因為非索引欄位更

新不需要對索引進行維護。

有時候我們需要對某個欄位進行去重,使用 DISTINCT,那麼對這個欄位創建索引,也會提升查詢效率。

比如,我們想要查詢課程表中不同的 student_id 都有哪些,如果我們沒有對 student_id 創建索引,執行

SQL 語句:

運行結果(600637 條記錄,運行時間 0.683s ):

如果我們對 student_id 創建索引,再執行 SQL 語句:

運行結果(600637 條記錄,運行時間 0.010s ):

你能看到 SQL 查詢效率有了提升,同時顯示出來的 student_id 還是按照 遞增的順序 進行展示的。這是因

為索引會對數據按照某種順序進行排序,所以在去重的時候也會快很多。

首先, 連接表的數量盡量不要超過 3 張 ,因為每增加一張表就相當於增加了一次嵌套的循環,數量級增

長會非常快,嚴重影響查詢的效率。

其次, 對 WHERE 條件創建索引 ,因為 WHERE 才是對數據條件的過濾。如果在數據量非常大的情況下,

沒有 WHERE 條件過濾是非常可怕的。

最後, 對用於連接的欄位創建索引 ,並且該欄位在多張表中的 類型必須一致 。比如 course_id 在

student_info 表和 course 表中都為 int(11) 類型,而不能一個為 int 另一個為 varchar 類型。

舉個例子,如果我們只對 student_id 創建索引,執行 SQL 語句:

運行結果(1 條數據,運行時間 0.189s ):

這里我們對 name 創建索引,再執行上面的 SQL 語句,運行時間為 0.002s 。

創建一張商戶表,因為地址欄位比較長,在地址欄位上建立前綴索引

問題是,截取多少呢?截取得多了,達不到節省索引存儲空間的目的;截取得少了,重復內容太多,字

段的散列度(選擇性)會降低。 怎麼計算不同的長度的選擇性呢?

先看一下欄位在全部數據中的選擇度:

通過不同長度去計算,與全表的選擇性對比:

公式:

例如:

引申另一個問題:索引列前綴對排序的影響

拓展:Alibaba《Java開發手冊》

【 強制 】在 varchar 欄位上建立索引時,必須指定索引長度,沒必要對全欄位建立索引,根據實際文本

區分度決定索引長度。

說明:索引的長度與區分度是一對矛盾體,一般對字元串類型數據,長度為 20 的索引,區分度會 高達

90% 以上 ,可以使用 count(distinct left(列名, 索引長度))/count(*)的區分度來確定。

這樣也可以較少的建立一些索引。同時,由於"最左前綴原則",可以增加聯合索引的使用率。

結論:在數據表中的數據行數比較少的情況下,比如不到 1000 行,是不需要創建索引的。

舉例1:要在 100 萬行數據中查找其中的 50 萬行(比如性別為男的數據),一旦創建了索引,你需要先

訪問 50 萬次索引,然後再訪問 50 萬次數據表,這樣加起來的開銷比不使用索引可能還要大。

舉例2:假設有一個學生表,學生總數為 100 萬人,男性只有 10 個人,也就是占總人口的 10 萬分之 1。

學生表 student_gender 結構如下。其中數據表中的 student_gender 欄位取值為 0 或 1,0 代表女性,1 代

表男性。

如果我們要篩選出這個學生表中的男性,可以使用:

運行結果(10 條數據,運行時間 0.696s ):

結論:當數據重復度大,比如 高於 10% 的時候,也不需要對這個欄位使用索引。

例如身份證、UUID(在索引比較時需要轉為ASCII,並且插入時可能造成頁分裂)、MD5、HASH、無序長字

符串等。

① 冗餘索引

舉例:建表語句如下

我們知道,通過 idx_name_birthday_phone_number 索引就可以對 name 列進行快速搜索,再創建一

個專門針對 name 列的索引就算是一個 冗餘索引 ,維護這個索引只會增加維護的成本,並不會對搜索有

什麼好處。

② 重復索引

另一種情況,我們可能會對某個列 重復建立索引 ,比方說這樣:

我們看到,col1 既是主鍵、又給它定義為一個唯一索引,還給它定義了一個普通索引,可是主鍵本身就

會生成聚簇索引,所以定義的唯一索引和普通索引是重復的,這種情況要避免。

歡迎共同進步:
QQ群:1007576722
https://huchao.blog.csdn.net/article/details/124220802?spm=1001.2014.3001.5502

資料庫索引有哪幾種怎樣建立索引

1、按照索引列值的唯一性,索引可分為唯一索引和非唯一索引;

create index 索引名 on 表名(列名) tablespace表空間名;

建立主鍵或者唯一約束時會自動在對應的列上建立唯一索引;

2、索引列的個數:單列索引和復合索引;

3、按照索引列的物理組織方式。

CREATEUNIUQE|BITMAPINDEX<schema>.<index_name>ON<schema>.<table_name>(<column_name>|<expression>ASC|DESC,<column_name>|<expression>ASC|DESC,...)TABLESPACE<tablespace_name>STORAGE<storage_settings>LOGGING||COMPRESS<nn>NOSORT|REVERSEPARTITION|GLOBALPARTITION<partition_setting>

使用USER_IND_COLUMNS查詢某個TABLE中的相應欄位索引建立情況

使用DBA_INDEXES/USER_INDEXES查詢所有索引的具體設置情況。

在Oracle中的索引可以分為:B樹索引、點陣圖索引、反向鍵索引、基於函數的索引、簇索引、全局索引、局部索引等,下面逐一講解:

一、B樹索引:

最常用的索引,各葉子節點中包括的數據有索引列的值和數據表中對應行的ROWID,簡單的說,在B樹索引中,是通過在索引中保存排過續的索引列值與相對應記錄的ROWID來實現快速查詢的目的。其邏輯結構如圖:

可以保證無論用戶要搜索哪個分支的葉子結點,都需要經過相同的索引層次,即都需要相同的I/O次數。

B樹索引的創建示例:

create index ind_t on t1(id);

注1:索引的針對欄位創建的,相同欄位不能創建一個以上的索引;

注2:默認的索引是不唯一的,但是也可以加上unique,表示該索引的欄位上沒有重復值(定義unique約束時會自動創建);

注3:創建主鍵時,默認在主鍵上創建了B樹索引,因此不能再在主鍵上創建索引。

二、點陣圖索引:

有些欄位中使用B樹索引的效率仍然不高,例如性別的欄位中,只有「男、女」兩個值,則即便使用了B樹索引,在進行檢索時也將返回接近一半的記錄。

所以當欄位的基數很低時,需要使用點陣圖索引。(「低」的標準是取值數量 < 行數*1%)

反向鍵索引是一種特殊的B樹索引,在存儲構造中與B樹索引完全相同,但是針對數值時,反向鍵索引會先反向每個鍵值的位元組,然後對反向後的新數據進行索引。例如輸入2008則轉換為8002,這樣當數值一次增加時,其反向鍵在大小中的分布仍然是比較平均的。

反向鍵索引的創建示例:

createindex ind_t on t1(id) reverse;

註:鍵的反轉由系統自行完成。對於用戶是透明的。

四、基於函數的索引:

有的時候,需要進行如下查詢:select * from t1 where to_char(date,'yyyy')>'2007';

但是即便在date欄位上建立了索引,還是不得不進行全表掃描。在這種情況下,可以使用基於函數的索引。其創建語法如下:

create index ind_t on t1(to_char(date,'yyyy'));

註:簡單來說,基於函數的索引,就是將查詢要用到的表達式作為索引項。

五、全局索引和局部索引:

這個索引貌似很復雜,其實很簡單。總得來說一句話,就是無論怎麼分區,都是為了方便管理。

具體索引和表的關系有三種:

1、局部分區索引:分區索引和分區表1對1

2、全局分區索引:分區索引和分區表N對N

3、全局非分區索引:非分區索引和分區表1對N

創建示例:

首先創建一個分區表

createtable student

(

stuno number(5),

sname vrvhar2(10),

deptno number(5)

)

partition by hash (deptno)

(

partition part_01 tablespace A1,

partition part_02 tablespace A2

);

創建局部分區索引(1v1):

create index ind_t on student(stuno)

local(

partition part_01 tablespace A2,

partition part_02 tablespace A1

);--local後面可以不加

創建全局分區索引(NvN):

create index ind_t on student(stuno)

globalpartition by range(stuno)

(

partition p1 values less than(1000) tablespace A1,

partition p2 values less than(maxvalue) tablespace A2

);--只可以進行range分區

創建全局非分區索引(1vN)

createindex ind_t on student(stuno) GLOBAL;

閱讀全文

與資料庫哪些列適合索引相關的資料

熱點內容
電纜批發市場怎麼找貨源 瀏覽:1
房產交易後多久出證 瀏覽:749
小店產品怎麼在直播間顯示 瀏覽:844
如何把產品賣出好價 瀏覽:69
數據生產要素怎麼界定 瀏覽:155
找人代理開店怎麼樣 瀏覽:515
如何營造買方市場 瀏覽:985
越南買什麼產品最好 瀏覽:573
返回程序是什麼指令 瀏覽:21
多腳晶元如何讀寫程序 瀏覽:562
常見的點雲數據的表達形式有哪些 瀏覽:904
轉轉交易中怎麼取消訂單 瀏覽:669
房價交易稅怎麼算 瀏覽:94
電話線上如何挖掘客戶信息 瀏覽:138
如何登錄小程序優化 瀏覽:685
產品gmv以及毛利率是什麼 瀏覽:146
閑魚交易量提高有什麼優勢 瀏覽:150
人事代理需要考什麼證 瀏覽:922
個人如何自己做一個產品 瀏覽:402
動物產品加工場所如何申報檢疫 瀏覽:174