mysql 索引:類型 、創建

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

一個簡單的對比測試

以我去年測試的數據作為一個簡單示例,20多條數據源隨機生成200萬條數據,平均每條數據源都重復大概10萬次,表結構比較簡單,僅包含一個自增ID,一個char類型,一個text類型和一個int類型,單表2G大小,使用MyIASM引擎。開始測試未添加任何索引。

執行下面的SQL語句:

1mysql>?SELECT?id,FROM_UNIXTIME(time)?FROM?article?WHERE?a.title='測試標題'

查詢需要的時間非常恐怖的,如果加上聯合查詢和其他一些約束條件,數據庫會瘋狂的消耗內存,并且會影響前端程序的執行。這時給title字段添加一個BTREE索引:

1mysql>?ALTER?TABLE?article?ADD?INDEX?index_article_title?ON?title(200);

再次執行上述查詢語句,其對比非常明顯:

?

MySQL索引的概念

索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含著對數據表里所有記錄的引用指針。更通俗的說,數據庫索引好比是一本書前面的目錄,能加快數據庫的查詢速度。上述SQL語句,在沒有索引的情況下,數據庫會遍歷全部200條數據后選擇符合條件的;而有了相應的索引之后,數據庫會直接在索引中查找符合條件的選項。如果我們把SQL語句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數據庫按照順序讀取完200萬行數據以后給你結果還是直接在索引中定位呢?上面的兩個圖片鮮明的用時對比已經給出了答案(注:一般數據庫默認都會為主鍵生成索引)。

索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數據存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對于單行的檢索很快。

MySQL索引的類型

1. 普通索引

這是最基本的索引,它沒有任何限制,比如上文中為title字段創建的索引就是一個普通索引,MyIASM中默認的BTREE類型的索引,也是我們大多數情況下用到的索引。

01–直接創建索引
02CREATE?INDEX?index_name?ON?table(column(length))
03–修改表結構的方式添加索引
04ALTER?TABLE?table_name?ADD?INDEX?index_name?ON?(column(length))
05–創建表的時候同時創建索引
06CREATE?TABLE?`table` (
07`id`?int(11)?NOT?NULL?AUTO_INCREMENT ,
08`title`?char(255)?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NOT?NULL?,
09`content` text?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NULL?,
10`time`?int(10)?NULL?DEFAULT?NULL?,
11PRIMARY?KEY?(`id`),
12INDEX?index_name (title(length))
13)
14–刪除索引
15DROP?INDEX?index_name?ON?table

2. 唯一索引

與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,創建方法和普通索引類似。

01–創建唯一索引
02CREATE?UNIQUE?INDEX?indexName?ON?table(column(length))
03–修改表結構
04ALTER?TABLE?table_name?ADD?UNIQUE?indexName?ON?(column(length))
05–創建表的時候直接指定
06CREATE?TABLE?`table` (
07`id`?int(11)?NOT?NULL?AUTO_INCREMENT ,
08`title`?char(255)?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NOT?NULL?,
09`content` text?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NULL?,
10`time`?int(10)?NULL?DEFAULT?NULL?,
11PRIMARY?KEY?(`id`),
12UNIQUE?indexName (title(length))
13);

3. 全文索引(FULLTEXT)

MySQL從3.23.23版開始支持全文索引和全文檢索,FULLTEXT索引僅可用于 MyISAM 表;他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創建,或是隨后使用ALTER TABLE 或CREATE INDEX被添加。對于較大的數據集,將你的資料輸入一個沒有FULLTEXT索引的表中,然后創建索引,其速度比把資料輸入現有FULLTEXT索引的速度更為快。不過切記對于大容量的數據表,生成全文索引是一個非常消耗時間非常消耗硬盤空間的做法。

01–創建表的適合添加全文索引
02CREATE?TABLE?`table` (
03`id`?int(11)?NOT?NULL?AUTO_INCREMENT ,
04`title`?char(255)?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NOT?NULL?,
05`content` text?CHARACTER?SET?utf8?COLLATE?utf8_general_ci?NULL?,
06`time`?int(10)?NULL?DEFAULT?NULL?,
07PRIMARY?KEY?(`id`),
08FULLTEXT (content)
09);
10–修改表結構添加全文索引
11ALTER?TABLE?article?ADD?FULLTEXT index_content(content)
12–直接創建索引
13CREATE?FULLTEXT?INDEX?index_content?ON?article(content)

4. 單列索引、多列索引

多個單列索引與單個多列索引的查詢效果不同,因為執行查詢時,MySQL只能使用一個索引,會從多個索引中選擇一個限制最為嚴格的索引。

5. 組合索引(最左前綴)

平時用的SQL查詢語句一般都有比較多的限制條件,所以為了進一步榨取MySQL的效率,就要考慮建立組合索引。例如上表中針對title和time建立一個組合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立這樣的組合索引,其實是相當于分別建立了下面兩組組合索引:

–title,time

–title

為什么沒有time這樣的組合索引呢?這是因為MySQL組合索引“最左前綴”的結果。簡單的理解就是只從最左面的開始組合。并不是只要包含這兩列的查詢都會用到該組合索引,如下面的幾個SQL所示:

1–使用到上面的索引
2SELECT?*?FROM?article WHREE title='測試'?AND?time=1234567890;
3SELECT?*?FROM?article WHREE utitle='測試';
4–不使用上面的索引
5SELECT?*?FROM?article WHREE?time=1234567890;

MySQL索引的優化

上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。建立索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快。索引只是提高效率的一個因素,如果你的MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。下面是一些總結以及收藏的MySQL索引的注意事項和優化方法。

1. 何時使用聚集索引或非聚集索引?

動作描述使用聚集索引使用非聚集索引
列經常被分組排序使用使用
返回某范圍內的數據使用不使用
一個或極少不同值不使用不使用
小數目的不同值使用不使用
大數目的不同值不使用使用
頻繁更新的列不使用使用
外鍵列使用使用
主鍵列使用使用
頻繁修改索引列不使用使用

事實上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某范圍內的數據一項。比如您的某個表有一個時間列,恰好您把聚合索引建立在了該列,這時您查詢2004年1月1日至2004年10月1日之間的全部數據時,這個速度就將是很快的,因為您的這本字典正文是按日期進行排序的,聚類索引只需要找到要檢索的所有數據中的開頭和結尾數據即可;而不像非聚集索引,必須先查到目錄中查到每一項數據對應的頁碼,然后再根據頁碼查到具體內容。其實這個具體用法我還不是很理解,只能等待后期的項目開發中慢慢學學了。

2. 索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那么這一列對于此復合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值為NULL。

3. 使用短索引

對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字符內,多數值是惟一的,那么就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。

4. 索引列排序

MySQL查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那么order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。

5. like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。

6. 不要在列上進行運算

例如:select * from users where YEAR(adddate)<2007,將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成:select * from users where adddate<’2007-01-01′。關于這一點可以圍觀:一個單引號引發的MYSQL性能損失。

最后總結一下,MySQL只對一下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些時候的like(不以通配符%或_開頭的情形)。而理論上每張表里面最多可創建16個索引,不過除非是數據量真的很多,否則過多的使用索引也不是那么好玩的,比如我剛才針對text類型的字段創建索引的時候,系統差點就卡死了。

?

轉自:https://www.cnblogs.com/lihuiyong/p/5623191.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448485.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448485.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448485.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

水調歌頭·中秋

轉載于:https://www.cnblogs.com/divineka/archive/2004/09/04/39560.html

代碼面試最常用的10大算法

摘要&#xff1a;面試也是一門學問&#xff0c;在面試之前做好充分的準備則是成功的必須條件&#xff0c;而程序員在代碼面試時&#xff0c;常會遇到編寫算法的相關問題&#xff0c;比如排序、二叉樹遍歷等等。 在程序員的職業生涯中&#xff0c;算法亦算是一門基礎課程&#…

fork與vfork的區別

fork與vfork的區別 1.vfork保證子進程先運行&#xff0c;在它調用exec或exit之后父進程才可能被調度運行。如果在調用這兩個函數之前子進程依賴于父進程的進一步動作&#xff0c;則會導致死鎖。 2.fork要拷貝父進程的進程環境&#xff1b;而vfork則不需要完全拷貝父進程的進程…

IDEA 2018 集成 MyBatis Generator 插件 詳解、代碼生成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1、修改maven的pom文件 只需要將如下依賴添加到pom.xml文件中即可。&#xff08;注意此處是以plugin的方式&#xff0c;放在<plugins…

MongoDB監控及報警

轉載請注明出處&#xff1a;https://www.cnblogs.com/shining5/p/11142357.html MongoDB監控及報警 Prometheus是由SoundCloud開發的開源監控報警系統和時序列數據庫&#xff0c;其使用go語言開發。基本原理是通過HTTP協議周期性抓取被監控組件的狀態&#xff0c;任意組件只要提…

umask命令:設置文件的默認權限掩碼

今天接觸到了掩碼&#xff0c;從博客上總結了一些關于掩碼解釋比較全面的分析&#xff0c;和大家分享下。 文件權限是linux系統中的一種安全機制&#xff0c;通過設置不同的權限&#xff0c;可以達到限制用戶操作的目的&#xff0c;有效地保證了文件的完整性。 默認的情況下&…

如何學習開源項目及Ceph的淺析

摘要&#xff1a;開源技術的學習和采用確實存在著一定門檻&#xff0c;然而學習各種開源項目已經成為許多開發者不可回避的工作內容。那么&#xff0c;對于類似OpenStack的大型開源項目&#xff0c;開發者該如何著手&#xff0c;這里我們看章宇的分享。 【編者按】在 上一屆O…

Mybatis 中更新方法: updateByPrimaryKeySelective() 和 updateByPrimaryKey() 的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 int updateByPrimaryKeySelective(TbItem record); int updateByPrimaryKey(TbItem record); 上面的是逆轉工程生成的Mapper接口 對應…

SHT知識庫操作要點

1.保存文檔庫模板&#xff1a; 知識庫---設置---文檔庫設置---權限管理---將文檔另存為模板2.設置版本號&#xff1a;知識庫---設置---文檔庫設置---常規設置---版本控制設置3.設置文檔庫權限&#xff1a;列表---設置---文檔庫設置---此文檔庫的權限&#xff08;用戶組讀取列表…

淺談三種特殊進程:孤兒進程,僵尸進程和守護進程

昨天學了進程控制&#xff0c;就這三種特殊的進程研究了一下&#xff0c;其中也借鑒了一些前人總計的經驗。 1、孤兒進程 如果父進程先退出,子進程還沒退出那么子進程將被 托孤給init進程,這里子進程的父進程就是init進程(1號進程).其實還是很好理解的。 // 父進程先子進程退…

設計師為什么要學編程,開發者為什么要學設計?

摘要&#xff1a;設計師和開發者目前正處于互聯網的兩端&#xff0c;看著彼此做不同的工作。如果他們能互相學習對方的技術&#xff0c;那么會協作得更好。 很多開發者認為&#xff0c;設計師應該學會如何編寫代碼&#xff0c;這一點是真的&#xff1a;通過學習&#xff0c;設計…

git 查看遠程倉庫地址

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 就一個命令&#xff1a; git remote -v 如下&#xff1a;

tensorflow之tf.train.exponential_decay()指數衰減法

exponential_decay(learning_rate, global_steps, decay_steps, decay_rate, staircaseFalse, nameNone) 使用方式&#xff1a; tf.tf.train.exponential_decay() 例子&#xff1a; tf.train.exponential_decay(self.config.e_lr, self.e_global_steps&#xff0c;self.config…

wait( )和 waitpid( )

進程一旦調用了wait&#xff0c;就立即阻塞自己&#xff0c;由wait自動分析是否當前進程的某個子進程已經退出&#xff0c;如果讓它找到了這樣一個已經變成僵尸的子進程&#xff0c;wait就會收集這個子進程的信息&#xff0c;并把它徹底銷毀后返回&#xff1b;如果沒有找到這樣…

享受閱讀的十二個好習慣

嚴謹的國際閱讀率比較研究顯示&#xff0c;當下韓國國民人均閱讀量約為每年11本&#xff0c;法國約為8.4本&#xff0c;日本在8.4—8.5本之間。全世界每年閱讀書籍數量排名第一的是猶太人&#xff0c;平均每人一年讀書64本。而中國13億人口&#xff0c;扣除教科書&#xff0c;平…

在 vscode 中使用 Git :拉取、提交、克隆

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 PS&#xff1a;轉載此文后&#xff0c;網友在評論中提到還有其它方法&#xff0c;不過目前個人尚在研究中&#xff0c;有興趣的朋友們也可…

偶也要去上海Tech一把了

公司組織的&#xff0c;后天去&#xff0c;呵呵&#xff1a;&#xff09;希望能多認識一點博客園的兄弟姐妹轉載于:https://www.cnblogs.com/martinxj/archive/2004/09/14/42930.html

進程控制常用的一些操作

1、獲取進程的id int main0() {printf ("當前進程 ID %d\n", getpid());printf ("當前父進程&#xff1a;%d\n", getppid());printf ("當前用戶&#xff1a; %d\n", getuid());while (1);return 0; }2、fork 和 vfork之前的博客里有&#xf…

vscode 配置 git (配置、暫存、推送、拉取、免密)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 vscode 中對 git 進行了集成&#xff0c;很多操作只需點擊就能操作&#xff0c;無需寫一些 git 指令。 不過這就需要你對 vscode 進行配…

男女之間應該保留多少隱私

究竟&#xff0c;男女朋友之間&#xff0c;應該保留多少個人隱私? 我覺得&#xff0c;如果各自的隱私太多,那么&#xff0c;很難會相信彼此的愛能有多深濃。然而&#xff0c;如果兩個人沒有半點隱私,而且絕對坦誠。 彼此的行為和思想也沒有絲毫隱瞞的話,這種清白赤誠有如標…