1. 程式人生 > >資料庫查詢優化——Mysql索引

資料庫查詢優化——Mysql索引

工作一年了,也是第一次使用Mysql的索引。添加了索引之後的速度的提升,讓我驚歎不已。隔壁的老員工看到我的大驚小怪,平淡地回了一句“那肯定啊”。

對於任何DBMS,索引都是進行優化的最主要的因素。對於少量的資料,沒有合適的索引影響不是很大,但是,當隨著資料量的增加,效能會急劇下降。

小寶鴿試了一下,2.5萬資料單表中,無索引:200ms-700ms,新增索引後10ms-15ms,使用redis快取1ms-7ms,如果資料量更大的時候,索引效果將會更加明顯。更甚者,多表查詢。

索引原理

1、除了詞典,生活中隨處可見索引的例子,如火車站的車次表、圖書的目錄等。它們的原理都是一樣的,通過不斷的縮小想要獲得資料的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是我們總是通過同一種查詢方式來鎖定資料。

資料庫也是一樣,但顯然要複雜許多,因為不僅面臨著等值查詢,還有範圍查詢(>、<、between、in)、模糊查詢(like)、並集查詢(or)等等。資料庫應該選擇怎麼樣的方式來應對所有的問題呢?我們回想字典的例子,能不能把資料分成段,然後分段查詢呢?最簡單的如果1000條資料,1到100分成第一段,101到200分成第二段,201到300分成第三段……這樣查第250條資料,只要找第三段就可以了,一下子去除了90%的無效資料。但如果是1千萬的記錄呢,分成幾段比較好?稍有演算法基礎的同學會想到搜尋樹,其平均複雜度是lgN,具有不錯的查詢效能。但這裡我們忽略了一個關鍵的問題,複雜度模型是基於每次相同的操作成本來考慮的,資料庫實現比較複雜,資料儲存在磁碟上,而為了提高效能,每次又可以把部分資料讀入記憶體來計算,因為我們知道訪問磁碟的成本大概是訪問記憶體的十萬倍左右,所以簡單的搜尋樹難以滿足複雜的應用場景。

2、另外,比如學生資訊表,新增學生姓名索引,索引是在name上排序的。現在,當查詢某個學生資訊時,就不需要逐行搜尋全表,可以利用索引進行有序查詢(如二分查詢法),並快速定位到匹配的值,以節省大量搜尋時間。

3、是當資料量非常大,查詢涉及多個表時,使用索引往往能使查詢速度加快成千上萬倍。
例如,有3個未索引的表t1、t2、t3,分別只包含列c1、c2、c3,每個表分別含有1000行資料組成,指為1~1000的數值,查詢對應值相等行的查詢如下所示。

SELECT c1,c2,c3 FROM t1,t2,t3 WHERE c1=c2 AND c1=c3

此查詢結果應該為1000行,每行包含3個相等的值。在無索引的情況下處理此查詢,必須尋找3個表所有的組合,以便得出與WHERE子句相配的那些行。而可能的組合數目為1000×1000×1000(十億),顯然查詢將會非常慢。

如果對每個表進行索引,就能極大地加速查詢程序。利用索引的查詢處理如下。

(1)從表t1中選擇第一行,檢視此行所包含的資料。

(2)使用表t2上的索引,直接定位t2中與t1的值匹配的行。類似,利用表t3上的索引,直接定位t3中與來自t1的值匹配的行。

(3)掃描表t1的下一行並重復前面的過程,直到遍歷t1中所有的行。

在此情形下,仍然對錶t1執行了一個完全掃描,但能夠在表t2和t3上進行索引查詢直接取出這些表中的行,比未用索引時要快一百萬倍。

利用索引,MySQL加速了WHERE子句滿足條件行的搜尋,而在多表連線查詢時,在執行連線時加快了與其他表中的行匹配的速度。

索引的型別

MySQL的索引包括普通索引、唯一性索引、全文索引、單列索引、多列索引和空間索引等。

1.普通索引

在建立普通索引時,不附加任何限制條件。這類索引可以建立在任何資料型別中,其值是否唯一和非空由欄位本身的完整性約束條件決定。建立索引以後,查詢時可以通過索引進行查詢。例如,在student表的stu_id欄位上建立一個普通索引。查詢記錄時,就可以根據該索引進行查詢。

2.唯一性索引

使用UNIQUE引數可以設定索引為唯一性索引。在建立唯一性索引時,限制該索引的值必須是唯一的。例如,在student表的stu_name欄位中建立唯一性索引,那麼stu_name欄位的值就必需是唯一的。通過唯一性索引,可以更快速地確定某條記錄。主鍵就是一種特殊唯一性索引。

3.全文索引

使用FULLTEXT引數可以設定索引為全文索引。全文索引只能建立在CHAR、VARCHAR或TEXT型別的欄位上。查詢資料量較大的字串型別的欄位時,使用全文索引可以提高查詢速度。例如,student表的information欄位是TEXT型別,該欄位包含了很多的文字資訊。在information欄位上建立全文索引後,可以提高查詢information欄位的速度。MySQL資料庫從3.23.23版開始支援全文索引,但只有MyISAM儲存引擎支援全文檢索。在預設情況下,全文索引的搜尋執行方式不區分大小寫。但索引的列使用二進位制排序後,可以執行區分大小寫的全文索引。

4.單列索引

在表中的單個欄位上建立索引。單列索引只根據該欄位進行索引。單列索引可以是普通索引,也可以是唯一性索引,還可以是全文索引。只要保證該索引只對應一個欄位 即可。

5.多列索引

多列索引是在表的多個欄位上建立一個索引。該索引指向建立時對應的多個欄位,可以通過這幾個欄位進行查詢。但是,只有查詢條件中使用了這些欄位中第一個欄位時,索引才會被使用。例如,在表中的id、name和sex欄位上建立一個多列索引,那麼,只有查詢條件使用了id欄位時該索引才會被使用。

6.空間索引

使用SPATIAL引數可以設定索引為空間索引。空間索引只能建立在空間資料型別上,這樣可以提高系統獲取空間資料的效率。MySQL中的空間資料型別包括GEOMETRY和POINT、LINESTRING和POLYGON等。目前只有MyISAM儲存引擎支援空間檢索,而且索引的欄位不能為空值。對於初學者來說,這類索引很少會用到。

索引的操作

1.新增PRIMARY KEY(主鍵索引)

mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 

2.新增UNIQUE(唯一索引)

mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 

3.新增INDEX(普通索引)

mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 

4.新增FULLTEXT(全文索引)

mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 

5.新增多列索引

mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

建立索引

在執行CREATE TABLE語句時可以建立索引,也可以單獨用CREATE INDEX或ALTER TABLE來為表增加索引。

1.ALTER TABLE

ALTER TABLE用來建立普通索引、UNIQUE索引或PRIMARY KEY索引。

ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)

其中table_name是要增加索引的表名,column_list指出對哪些列進行索引,多列時各列之間用逗號分隔。索引名index_name可選,預設時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE允許在單個語句中更改多個表,因此可以在同時建立多個索引。

2.CREATE INDEX

CREATE INDEX可對錶增加普通索引或UNIQUE索引。

CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句建立PRIMARY KEY索引。

3.索引型別

在建立索引時,可以規定索引能否包含重複值。如果不包含,則索引應該建立為PRIMARY KEY或UNIQUE索引。對於單列惟一性索引,這保證單列不包含重複的值。對於多列惟一性索引,保證多個值的組合不重複。
PRIMARY KEY索引和UNIQUE索引非常類似。事實上,PRIMARY KEY索引僅是一個具有名稱PRIMARY的UNIQUE索引。這表示一個表只能包含一個PRIMARY KEY,因為一個表中不可能具有兩個同名的索引。

下面的SQL語句對students表在sid上新增PRIMARY KEY索引。

ALTER TABLE students ADD PRIMARY KEY (sid)

刪除索引

可利用ALTER TABLE或DROP INDEX語句來刪除索引。類似於CREATE INDEX語句,DROP INDEX可以在ALTER TABLE內部作為一條語句處理,語法如下。

DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY

其中,前兩條語句是等價的,刪除掉table_name中的索引index_name。

第3條語句只在刪除PRIMARY KEY索引時使用,因為一個表只可能有一個PRIMARY KEY索引,因此不需要指定索引名。如果沒有建立PRIMARY KEY索引,但表具有一個或多個UNIQUE索引,則MySQL將刪除第一個UNIQUE索引。

如果從表中刪除了某列,則索引會受到影響。對於多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。

注:一般資料庫預設都會為主鍵生成索引

相關推薦

資料庫查詢優化——Mysql索引

工作一年了,也是第一次使用Mysql的索引。添加了索引之後的速度的提升,讓我驚歎不已。隔壁的老員工看到我的大驚小怪,平淡地回了一句“那肯定啊”。 對於任何DBMS,索引都是進行優化的最主要的因素。對於少量的資料,沒有合適的索引影響不是很大,但是,當隨著資料量的

mysql數據庫-查詢優化索引

mys 結構 details 速查 dex 主鍵 alt key 數據結構 定義:是數據庫中專門用於幫助用戶快速查詢數據的一種數據結構。類似於字典中的目錄,查找字典內容時可以根據目錄查找到數據的存放位置,然後直接獲取即可。 分類:普通索引,唯一性索引,全文索引,單列索引,多

MySQL百萬級資料庫查詢優化技巧

1.對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: select id from t where nu

mysql效能調優筆記(二)--查詢優化索引

一、Mysql執行查詢流程                                                                           mysql執行查詢的流程 mysql執行查詢內部路程:1.客服端傳送一條查詢給伺服器

阿里P7架構師談:MySQL查詢優化索引優化、以及表等優化總結

MySQL優化概述 MySQL資料庫常見的兩個瓶頸是:CPU和I/O的瓶頸。 CPU在飽和的時候一般發生在資料裝入記憶體或從磁碟上讀取資料時候。 磁碟I/O瓶頸發生在裝入資料遠大於記憶體容量的時候,如果應用分佈在網路上,那麼查詢量相當大的時候那麼平瓶頸就會出現在網路上。

MySQL查詢優化索引條件下推

原文地址:https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html 譯文: 8.2.1.5 索引條件下推優化 索引條件下推(ICP)是當MySQL使用索引從表中檢索行時使用的一種優

MySQL查詢優化索引合併

原文地址:https://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html 譯文: 8.2.1.3 索引合併優化 索引合併訪問方法使用多範圍掃描檢索行,並把檢索結果合併成一個。這種訪問方法僅合併來自單個表的索引掃描

mysql資料庫查詢優化-快取

查詢執行的基礎 一.基礎 當希望mysql能夠以更高的效能執行查詢時,最好的辦法就是弄清楚mysql是如何優化和執行查詢的,基本可以從以下3點開始瞭解: 1.客戶端和mysql伺服器的互動過程 (1)客戶端傳送一條查詢給伺服器 (2)伺服器先檢查查詢快取(第二次查詢的SQL和第一次查詢

mysql資料庫查詢優化

總結: 儘可能減少掃表的行數,達到目的 查詢執行的基礎 一.基礎 當希望mysql能夠以更高的效能執行查詢時,最好的辦法就是弄清楚mysql是如何優化和執行查詢的,基本可以從以下3點開始瞭解: 1.客戶端和mysql伺服器的互動過程 (1)客戶端傳送一條查詢給伺服器 (2)伺服器先檢查

MySQL 資料庫效能優化索引優化

非常感謝作者。 大家都知道索引對於資料訪問的效能有非常關鍵的作用,都知道索引可以提高資料訪問效率。 為什麼索引能提高資料訪問效能?他會不會有“副作用”?是不是索引建立越多,效能就越好?到底該如何設計索引,才能最大限度的發揮其效能? 這篇文章主要是帶著上面這幾個問題來做一個

煉數成金MySql視訊教程 MySQL資料庫查詢優化技術 15周課程深入學習MySQL資料庫查詢

課程介紹:這套課程將會帶領大家進行一次MySQL資料庫查詢優化的深入體驗,對於從事MySQL運維的朋友來說必不可少!課程大綱:1 資料庫與關係代數2 資料庫查詢優化技術總攬3 查詢優化技術理論與MySQL實踐(一)------子查詢的優化(一)4 查詢優化技術理論與MySQL

大資料量表的查詢優化索引使用

一、對於運算邏輯,儘可能將要統計的各專案整合在一個查詢語句中計算,而不是用分組條件或分專案呼叫多個查詢語句,而後在程式碼裡計算結果。 二、查詢語句的優化,諸如不用"select *"、多表關聯查詢時新增別名於查詢欄位上、避免使用in、not in關鍵字、非去除重複時用union all替換uni

易學筆記-系統分析師考試-第5章 資料庫系統/5.6 分散式資料庫系統/5.6.3 分散式資料庫查詢優化

查詢優化對比 集中式資料庫:主要考慮CPU和I/O代價 分散式資料庫:除了考慮CPU和I/O代價,還要考慮通訊代價 分散式查詢分類 區域性查詢:類似於集中式資料庫查詢,可用集中式資料庫查詢方法優化 遠端查詢:使用者查詢只涉及到網路中單個場地

資料庫查詢優化技術(二):子查詢優化

查詢的基本操作     1選擇操作 對應的是限制條件(格式類似“field<op>consant”, field表示列物件,op是操作符如"="、">"等)。 操作物件是二維表中的行 優化方式: 選擇操作下推 目的: 是儘

資料庫查詢優化技術(一):資料庫與關係代數

資料庫查詢優化技術 學習筆記(一)   我是看李海翔的《資料庫技術叢書·資料庫查詢優化器的藝術:原理解析與SQL效能優化》這本書的視訊講解學習的,因為資料庫的知識學的不多,直接看優化有些吃力,慢慢補吧。現在要用一些優化的知識只能先看著了。   本文大概內容:

快閃記憶體資料庫查詢優化

在關係型資料庫中,會涉及到大量的查詢操作,查詢操作往往還涉及不同表之間的連線操作,而連線操作需要大量的IO開銷,傳統的資料庫的查詢優化都在順序IO上優化,到快閃記憶體上,快閃記憶體的隨機讀和順序讀效能都很出色,那麼面對隨機讀效能好的優勢,在查詢和連線索引上,資料

資料庫查詢優化(使用union 和 union all 的區別)

在專案中遇到一個問題,建立一個檢視,主要內容是: SELECT   info.InfoCode, info.YearOfData, info.MonthOfData, info.ProjectPropertyID, property.PropertyName, info.P

資料庫查詢優化問題

原先資料庫沒有好好學習,感覺一直是似懂非懂的狀態,很多原理也不懂,今天抽時間查閱一些資料自己也總結了一些。 本文資料庫索引原理部分主要參考博文:http://www.cnblogs.com/aspwe

資料庫查詢優化引擎可以怎樣實現查詢優化--邏輯查詢優化

本節大部分的資料來自《資料庫查詢優化的藝術》 23頁到第二章結束的內容 最常見的子查詢優化 IN 型別的優化 1.OUT_EXP (NOT) IN INNER_EXP_SELECT_SQL 2.OUT_EXP = ANY INNER_EXP_SELECT_SQL 第一種情況

資料庫查詢優化引擎可以怎樣實現查詢優化---開篇

前言 資料庫的優化體現在各個優化引擎上,一個數據庫能否流行起來,也是取決於資料庫本身的優化引擎的優劣。而優化也是分幾個階段,比如,第一個階段是需求分析,這時候就是對資料庫的選型,系統的選型做,應用的策略做判斷,第二個階段是基於選好優化器的基礎上進行資料模型的設計,這個階段會產生需求體現的