A. MYSQL資料庫索引類型都有哪些
在滿足語句需求的情況下,盡量少的訪問資源是資料庫設計的重要原則,這和執行的 SQL 有直接的關系,索引問題又是 SQL 問題中出現頻率最高的,常見的索引問題包括:無索引(失效)、隱式轉換。
1. SQL 執行流程看一個問題,在下面這個表 T 中,如果我要執行 select * from T where k between 3 and 5; 需要執行幾次樹的搜索操作,會掃描多少行?mysql> create table T ( -> ID int primary key, -> k int NOT NULL DEFAULT 0, -> s varchar(16) NOT NULL DEFAULT '', -> index k(k)) -> engine=InnoDB;mysql> insert into T values(100,1, 'aa'),(200,2,'bb'), (300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');
這分別是 ID 欄位索引樹、k 欄位索引樹。
這條 SQL 語句的執行流程:
1. 在 k 索引樹上找到 k=3,獲得 ID=3002. 回表到 ID 索引樹查找 ID=300 的記錄,對應 R33. 在 k 索引樹找到下一個值 k=5,ID=5004. 再回到 ID 索引樹找到對應 ID=500 的 R4
5. 在 k 索引樹去下一個值 k=6,不符合條件,循環結束
這個過程讀取了 k 索引樹的三條記錄,回表了兩次。因為查詢結果所需要的數據只在主鍵索引上有,所以必須得回表。所以,我們該如何通過優化索引,來避免回表呢?
2. 常見索引優化2.1 覆蓋索引覆蓋索引,換言之就是索引要覆蓋我們的查詢請求,無需回表。
如果執行的語句是 select ID from T wherek between 3 and 5;,這樣的話因為 ID 的值在 k 索引樹上,就不需要回表了。
覆蓋索引可以減少樹的搜索次數,顯著提升查詢性能,是常用的性能優化手段。
但是,維護索引是有代價的,所以在建立冗餘索引來支持覆蓋索引時要權衡利弊。
2.2 最左前綴原則
B+ 樹的數據項是復合的數據結構,比如 (name,sex,age) 的時候,B+ 樹是按照從左到右的順序來建立搜索樹的,當 (張三,F,26) 這樣的數據來檢索的時候,B+ 樹會優先比較 name 來確定下一步的檢索方向,如果 name 相同再依次比較 sex 和 age,最後得到檢索的數據。
# 有這樣一個表 P
mysql> create table P (id int primary key, name varchar(10) not null, sex varchar(1), age int, index tl(name,sex,age)) engine=IInnoDB;
mysql> insert into P values(1,'張三','F',26),(2,'張三','M',27),(3,'李四','F',28),(4,'烏茲','F',22),(5,'張三','M',21),(6,'王五','M',28);
# 下面的語句結果相同
mysql> select * from P where name='張三' and sex='F'; ## A1
mysql> select * from P where sex='F' and age=26; ## A2
# explain 看一下
mysql> explain select * from P where name='張三' and sex='F';
+----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | P | NULL | ref | tl | tl | 38 | const,const | 1 | 100.00 | Using index |
+----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
mysql> explain select * from P where sex='F' and age=26;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | P | NULL | index | NULL | tl | 43 | NULL | 6 | 16.67 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
2.3 索引下推
2.4 隱式類型轉化
修改應用,將應用中傳入的字元類型改為與表結構相同類型。
3.2 掃描行數
在 MySQL 中,有兩種存儲索引統計的方式,可以通過設置參數 innodb_stats_persistent 的值來選擇:
on 表示統計信息會持久化存儲。默認 N = 20,M = 10。
off 表示統計信息只存儲在內存中。默認 N = 8,M = 16。
可以用 analyze table 來重新統計索引信息,進行修正。
B. mysql資料庫中的索引有那些,有什麼用
索引可以理解為對數據的一個編碼。如果把資料庫比作一本書,那麼索引就是頁碼,可以根據這個快速的去查詢。比喻不恰當之處,還請大神高手多多指教。
C. 資料庫表的索引有幾種啊
1.普通索引、主鍵索引、唯一索引
2.並非所有的資料庫都以相同的方式使用索引,作為通用規則,只有當經常查詢列中的數據時才需要在表上創建索引。
D. 資料庫中的索引是什麼意思有什麼用途
索引是一種單獨的、物理的對資料庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。
一個索引是存儲的表中一個特定列的值數據結構(最常見的是B-Tree,還有哈希表索引和R-tree)。索引是在表的列上創建。所以,要記住的關鍵點是索引包含一個表中列的值,並且這些值存儲在一個數據結構中。請記住記住這一點:索引是一種數據結構
使用索引的全部意義就是通過縮小一張表中需要查詢的記錄(行)的數目來加快搜索的速度。
假設有一張學生名單表,有一百條數據。要查詢其中名字為 小明 的學生。
一般採取select * from students where name ='小明';由於我們想要得到每一個名字為小明的學生信息,在查詢到第一個符合條件的行後,不能停止查詢,因為可能還有其他符合條件的行。所以,必須一行一行的查找直到最後一行-這就意味資料庫不得不檢查上千行數據才能找到所以名字為小明的學生。這就是所謂的全表掃描。
假設我們在 name這一列上創建一個B-Tree索引。當我們用SQL查找名字是『小明』的學生時,不需要再掃描全表。而是用索引查找去查找名字為『小明』的學生,因為索引已經按照按字母順序排序。索引已經排序意味著查詢一個名字會快很多,因為名字首字母為『小』的學生都是排列在一起的。另外重要的一點是,索引同時存儲了表中相應行的指針以獲取其他列的數據。
E. 資料庫中的索引是什麼意思
什麼是索引:
索引是資料庫存儲引擎用於快速查找到指定數據的一種數據結構。
可以用新華字典做類比:如果新華字典中對每個字的詳細解釋是資料庫中表的記錄,那麼按部首或拼音等排序的目錄就是索引,使用它可以讓我們快速查找的某一個字詳細解釋的位置。
在MySQL中,存儲引擎也是用了類似的方法,先在索引中找到對應的值,然後再根據匹配的索引值找到對應表中記錄的位置。
面試中為什麼問索引:
之所以在索引在面試中經常被問到,就是因為:索引是資料庫的良好性能表現的關鍵,也是對查詢能優化最有效的手段。索引能夠輕易地把查詢性能提高幾個數量級。
然而,糟糕的索引也同樣會影響查詢性能,當表中的數據量越來越多的時候,索引對性能的影響就越大。在數據量比較少並且負責比較低的時候,糟糕的索引對性能的影響可能不明顯,但是當數據量逐漸增多的時候,性能會急劇下降。
索引的類型:
不同類型的索引,可以為不同場景提供更好的性能。在MySQL中,索引是在存儲引擎層面實現的,而不是在伺服器層面實現的。正如大家所知道,MySQL支持多種類型的存儲引擎。所以,在不同存儲引擎中索引的實現方式並不是一樣的,也不是所有類型的索引都被所有存儲引擎支持的,即使多個存儲引擎支持同一種類型的索引,它底層的實現也有可能是不相同的。
F. 什麼是資料庫索引 有哪些類型和特點
資料庫索引的作用相當於書的目錄,就是提高數據的查詢速度,不同的資料庫索引類型不用,比如SQL SERVER就有聚集索引和非聚集索引,聚集索引提高數據的查詢速度,非聚集索引對提高查詢速度不利,但可以提高數據的刪除或插入速度,因為它的邏輯頁面和物理頁面不一致
G. 資料庫索引的主要種類
資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度。索引分為聚簇索引和非聚簇索引兩種,聚簇索引 是按照數據存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對於單行的檢索很快。
根據資料庫的功能,可以在資料庫設計器中創建三種索引:唯一索引、主鍵索引和聚集索引。有關資料庫所支持的索引功能的詳細信息,請參見資料庫文檔。
提示:盡管唯一索引有助於定位信息,但為獲得最佳性能結果,建議改用主鍵或唯一約束。
唯一索引 唯一索引是不允許其中任何兩行具有相同索引值的索引。
當現有數據中存在重復的鍵值時,大多數資料庫不允許將新創建的唯一索引與表一起保存。資料庫還可能防止添加將在表中創建重復鍵值的新數據。例如,如果在employee表中職員的姓(lname)上創建了唯一索引,則任何兩個員工都不能同姓。
主鍵索引
資料庫表經常有一列或多列組合,其值唯一標識表中的每一行。該列稱為表的主鍵。
在資料庫關系圖中為表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對數據的快速訪問。
聚集索引
在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引。
如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數據訪問速度。
索引列
可以基於資料庫表中的單列或多列創建索引。多列索引可以區分其中一列可能有相同值的行。
如果經常同時搜索兩列或多列或按兩列或多列排序時,索引也很有幫助。例如,如果經常在同一查詢中為姓和名兩列設置判據,那麼在這兩列上創建多列索引將很有意義。
確定索引的有效性:
檢查查詢的WHERE和JOIN子句。在任一子句中包括的每一列都是索引可以選擇的對象。
對新索引進行試驗以檢查它對運行查詢性能的影響。
考慮已在表上創建的索引數量。最好避免在單個表上有很多索引。
檢查已在表上創建的索引的定義。最好避免包含共享列的重疊索引。
檢查某列中唯一數據值的數量,並將該數量與表中的行數進行比較。比較的結果就是該列的可選擇性,這有助於確定該列是否適合建立索引,如果適合,確定索引的類型。
H. 資料庫索引是什麼,有什麼用,怎麼用
1、資料庫索引是什麼,有什麼用
資料庫索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定信息。如果想按特定職員的姓來查找他或她,則與在表中搜索所有的行相比,索引有助於更快地獲取信息。
索引的一個主要目的就是加快檢索表中數據的方法,亦即能協助信息搜索者盡快的找到符合限制條件的記錄ID的輔助數據結構。
2、資料庫索引的用法
當表中有大量記錄時,若要對表進行查詢,第一種搜索信息方式是全表搜索,是將所有記錄一一取出,和查詢條件進行一一對比,然後返回滿足條件的記錄,這樣做會消耗大量資料庫系統時間,並造成大量磁碟I/O操作;
第二種就是在表中建立索引,然後在索引中找到符合查詢條件的索引值,最後通過保存在索引中的ROWID(相當於頁碼)快速找到表中對應的記錄。
索引是一個單獨的、物理的資料庫結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識值的數據頁的邏輯指針清單。
(8)資料庫中的索引有哪些擴展閱讀:
一、索引的原理:
對要查詢的欄位建立索引其實就是把該欄位按照一定的方式排序;建立的索引只對該欄位有用,如果查詢的欄位改變,那麼這個索引也就無效了,比如圖書館的書是按照書名的第一個字母排序的,那麼你想要找作者叫張三的就不能用改索引了;還有就是如果索引太多會降低查詢的速度。
二、資料庫索引的特點:
1、避免進行資料庫全表的掃描,大多數情況,只需要掃描較少的索引頁和數據頁,而不是查詢所有數據頁。而且對於非聚集索引,有時不需要訪問數據頁即可得到數據。
2、聚集索引可以避免數據插入操作,集中於表的最後一個數據頁面。
3、在某些情況下,索引可以避免排序操作。
I. 資料庫索引有哪幾種怎樣建立索引
種類:
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;