日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

sql索引的建立与使用_sqlserver创建索引语句(廖雪峰的官方网站)

發(fā)布時(shí)間:2023/12/19 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 sql索引的建立与使用_sqlserver创建索引语句(廖雪峰的官方网站) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前在網(wǎng)上看到過很多關(guān)于mysql聯(lián)合索引最左前綴匹配的文章,自以為就了解了其原理,發(fā)現(xiàn)遺漏了些東西,這里自己整理一下這方面的內(nèi)容。

1 前言

SQL索引有兩種,聚集索引和非聚集索引

聚集索引存儲(chǔ)記錄是物理上連續(xù)存在,而非聚集索引是邏輯上的連續(xù),物理存儲(chǔ)并不連續(xù)

字典的拼音查詢法就是聚集索引,字典的部首查詢就是一個(gè)非聚集索引.

聚集索引和非聚集索引的根本區(qū)別是表記錄的排列順序和與索引的排列順序是否一致

聚集索引一個(gè)表只能有一個(gè),而非聚集索引一個(gè)表可以存在多個(gè)。

2 建立索引的原則:

1) 定義主鍵的數(shù)據(jù)列一定要建立索引。

2) 定義有外鍵的數(shù)據(jù)列一定要建立索引。

3) 對(duì)于經(jīng)常查詢的數(shù)據(jù)列最好建立索引。

4) 對(duì)于需要在指定范圍內(nèi)的快速或頻繁查詢的數(shù)據(jù)列;

5) 經(jīng)常用在WHERE子句中的數(shù)據(jù)列。

6) 經(jīng)常出現(xiàn)在關(guān)鍵字order by、group by、distinct后面的字段,建立索引。

如果建立的是復(fù)合索引,索引的字段順序要和這些關(guān)鍵字后面的字段順序一致,否則索引不會(huì)被使用。

7) 對(duì)于那些查詢中很少涉及的列,重復(fù)值比較多的列不要建立索引。

8) 對(duì)于定義為text、image和bit的數(shù)據(jù)類型的列不要建立索引。

9) 對(duì)于經(jīng)常存取的列避免建立索引

10) 限制表上的索引數(shù)目。對(duì)一個(gè)存在大量更新操作的表,所建索引的數(shù)目一般不要超過3個(gè),最多不要超過5個(gè)。

索引雖說提高了訪問速度,但太多索引會(huì)影響數(shù)據(jù)的更新操作。

11) 對(duì)復(fù)合索引,按照字段在查詢條件中出現(xiàn)的頻度建立索引。在復(fù)合索引中,記錄首先按照第一個(gè)字段排序。

對(duì)于在第一個(gè)字段上取值相同的記錄,系統(tǒng)再按照第二個(gè)字段的取值排序,以此類推。

因此只有復(fù)合索引的第一個(gè)字段出現(xiàn)在查詢條件中,該索引才可能被使用,因此將應(yīng)用頻度高的字段,放置在復(fù)合索引的前面,會(huì)使系統(tǒng)最大可能地使用此索引,發(fā)揮索引的作用。

2.1另外原則

1.最左前綴匹配原則

非常重要的原則,mysql會(huì)一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c >3 and d = 4. 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。

2.=和in可以亂序

比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優(yōu)化器會(huì)幫你優(yōu)化成索引可以識(shí)別的形式

3.盡量選擇區(qū)分度高的列作為索引

區(qū)分度的公式是count(distinct col)/count(*),表示字段不重復(fù)的比例,比例越大我們掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前區(qū)分度就是0,那可能有人會(huì)問,這個(gè)比例有什么經(jīng)驗(yàn)值嗎?使用場(chǎng)景不同,這個(gè)值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條記錄

4.索引列不能參與計(jì)算

保持列“干凈”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡(jiǎn)單,b+樹中存的都是數(shù)據(jù)表中的字段值,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較,顯然成本太大。所以語句應(yīng)該寫成create_time = unix_timestamp(’2014-05-29’);

5.盡量的擴(kuò)展索引,不要新建索引。

比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可

6.選擇唯一性索引

唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。例如,學(xué)生表中學(xué)號(hào)是具有唯一性的字段。為該字段建立唯一性索引可以很快的確定某個(gè)學(xué)生的信息。如果使用姓名的話,可能存在同名現(xiàn)象,從而降低查詢速度。

7.為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引

經(jīng)常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作會(huì)浪費(fèi)很多時(shí)間。如果為其建立索引,可以有效地避免排序操作。

8.為常作為查詢條件的字段建立索引

如果某個(gè)字段經(jīng)常用來做查詢條件,那么該字段的查詢速度會(huì)影響整個(gè)表的查詢速度。因此,為這樣的字段建立索引,可以提高整個(gè)表的查詢速度。

9.限制索引的數(shù)目

索引的數(shù)目不是越多越好。每個(gè)索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大。修改表時(shí),對(duì)索引的重構(gòu)和更新很麻煩。越多的索引,會(huì)使更新表變得很浪費(fèi)時(shí)間。

10.盡量使用數(shù)據(jù)量少的索引

如果索引的值很長(zhǎng),那么查詢的速度會(huì)受到影響。例如,對(duì)一個(gè)CHAR(100)類型的字段進(jìn)行全文檢索需要的時(shí)間肯定要比對(duì)CHAR(10)類型的字段需要的時(shí)間要多。

11.盡量使用前綴來索引

如果索引字段的值很長(zhǎng),最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進(jìn)行全文檢索會(huì)很浪費(fèi)時(shí)間。如果只檢索字段的前面的若干個(gè)字符,這樣可以提高檢索速度。

12.刪除不再使用或者很少使用的索引

表中的數(shù)據(jù)被大量更新,或者數(shù)據(jù)的使用方式被改變后,原有的一些索引可能不再需要。數(shù)據(jù)庫(kù)管理員應(yīng)當(dāng)定期找出這些索引,將它們刪除,從而減少索引對(duì)更新操作的影響。

2.2 最左前綴匹配原則

在mysql建立聯(lián)合索引時(shí)會(huì)遵循最左前綴匹配的原則,即最左優(yōu)先,在檢索數(shù)據(jù)時(shí)從聯(lián)合索引的最左邊開始匹配,示例:
對(duì)列col1、列col2和列col3建一個(gè)聯(lián)合索引

KEY test_col1_col2_col3 on test(col1,col2,col3);

聯(lián)合索引 test_col1_col2_col3 實(shí)際建立了(col1)、(col1,col2)、(col,col2,col3)三個(gè)索引。

SELECT*FROMtestWHEREcol1=“1”ANDclo2=“2”ANDclo4=“4”

上面這個(gè)查詢語句執(zhí)行時(shí)會(huì)依照最左前綴匹配原則,檢索時(shí)會(huì)使用索引(col1,col2)進(jìn)行數(shù)據(jù)匹配。

注意

索引的字段可以是任意順序的,如:

SELECT * FROM test WHERE col1=“1” AND clo2=“2”
SELECT * FROM test WHERE col2=“2” AND clo1=“1”

這兩個(gè)查詢語句都會(huì)用到索引(col1,col2),mysql創(chuàng)建聯(lián)合索引的規(guī)則是首先會(huì)對(duì)聯(lián)合合索引的最左邊的,也就是第一個(gè)字段col1的數(shù)據(jù)進(jìn)行排序,在第一個(gè)字段的排序基礎(chǔ)上,然后再對(duì)后面第二個(gè)字段col2進(jìn)行排序。其實(shí)就相當(dāng)于實(shí)現(xiàn)了類似 order by col1 col2這樣一種排序規(guī)則。

有人會(huì)疑惑第二個(gè)查詢語句不符合最左前綴匹配:首先可以肯定是兩個(gè)查詢語句都包含索引(col1,col2)中的col1、col2兩個(gè)字段,只是順序不一樣,查詢條件一樣,最后所查詢的結(jié)果肯定是一樣的。既然結(jié)果是一樣的,到底以何種順序的查詢方式最好呢?此時(shí)我們可以借助mysql查詢優(yōu)化器explain,explain會(huì)糾正sql語句該以什么樣的順序執(zhí)行效率最高,最后才生成真正的執(zhí)行計(jì)劃。

2.3 為什么要使用聯(lián)合索引

  • 減少開銷建一個(gè)聯(lián)合索引(col1,col2,col3),實(shí)際相當(dāng)于建了(col1),(col1,col2),(col1,col2,col3)三個(gè)索引。每多一個(gè)索引,都會(huì)增加寫操作的開銷和磁盤空間的開銷。對(duì)于大量數(shù)據(jù)的表,使用聯(lián)合索引會(huì)大大的減少開銷!
  • 覆蓋索引。對(duì)聯(lián)合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL可以直接通過遍歷索引取得數(shù)據(jù),而無需回表,這減少了很多的隨機(jī)io操作。減少io操作,特別的隨機(jī)io其實(shí)是dba主要的優(yōu)化策略。所以,在真正的實(shí)際應(yīng)用中,覆蓋索引是主要的提升性能的優(yōu)化手段之一。
  • 效率高。索引列越多,通過索引篩選出的數(shù)據(jù)越少。有1000W條數(shù)據(jù)的表,有如下sql:selectfrom table where col1=1 and col2=2 and col3=3,假設(shè)假設(shè)每個(gè)條件可以篩選出10%的數(shù)據(jù),如果只有單值索引,那么通過該索引能篩選出1000W10%=100w條數(shù)據(jù),然后再回表從100w條數(shù)據(jù)中找到符合col2=2 and col3= 3的數(shù)據(jù),然后再排序,再分頁;如果是聯(lián)合索引,通過索引篩選出1000w10%10% *10%=1w,效率提升可想而知!

引申

對(duì)于聯(lián)合索引(col1,col2,col3),查詢語句SELECT * FROM test WHERE col2=2;是否能夠觸發(fā)索引?
大多數(shù)人都會(huì)說NO,實(shí)際上卻是YES。
原因

EXPLAIN SELECT * FROM test WHERE col2=2;
EXPLAIN SELECT * FROM test WHERE col1=1;

觀察上述兩個(gè)explain結(jié)果中的type字段。查詢中分別是:

  1. type: index
  2. type: ref

index:這種類型表示mysql會(huì)對(duì)整個(gè)該索引進(jìn)行掃描。要想用到這種類型的索引,對(duì)這個(gè)索引并無特別要求,只要是索引,或者某個(gè)聯(lián)合索引的一部分,mysql都可能會(huì)采用index類型的方式掃描。但是呢,缺點(diǎn)是效率不高,mysql會(huì)從索引中的第一個(gè)數(shù)據(jù)一個(gè)個(gè)的查找到最后一個(gè)數(shù)據(jù),直到找到符合判斷條件的某個(gè)索引。所以,上述語句會(huì)觸發(fā)索引。
ref:這種類型表示mysql會(huì)根據(jù)特定的算法快速查找到某個(gè)符合條件的索引,而不是會(huì)對(duì)索引中每一個(gè)數(shù)據(jù)都進(jìn)行一一的掃描判 斷,也就是所謂你平常理解的使用索引查詢會(huì)更快的取出數(shù)據(jù)。而要想實(shí)現(xiàn)這種查找,索引卻是有要求的,要實(shí)現(xiàn)這種能快速查找的算法,索引就要滿足特定的數(shù)據(jù)結(jié)構(gòu)。簡(jiǎn)單說,也就是索引字段的數(shù)據(jù)必須是有序的,才能實(shí)現(xiàn)這種類型的查找,才能利用到索引。

3 聚集索引和非聚集索引

聚集索引和非聚集索引的根本區(qū)別是數(shù)據(jù)記錄的排列順序和索引的排列順序是否一致,聚集索引表記錄的排列順序與索引的排列順序一致,優(yōu)點(diǎn)是查詢速度快,因?yàn)橐坏┚哂械谝粋€(gè)索引值的紀(jì)錄被找到,具有連續(xù)索引值的記錄也一定物理的緊跟其后,從而縮小了搜索范圍,對(duì)于返回某一范圍的數(shù)據(jù)效果最好。

聚集索引的缺點(diǎn)是對(duì)表進(jìn)行修改速度較慢,這是為了保持表中的記錄的物理順序與索引的順序一致,而把記錄插入到數(shù)據(jù)頁的相應(yīng)位置,必須在數(shù)據(jù)頁中進(jìn)行數(shù)據(jù)重排,降低了執(zhí)行速度。
  非聚集索引指定了表中記錄的邏輯順序,數(shù)據(jù)記錄的物理順序和索引的順序不一致,聚集索引和非聚集索引都采用了B樹的結(jié)構(gòu),但非聚集索引的葉子層順序并不與實(shí)際的數(shù)據(jù)頁相同,而采用指向表中的記錄在數(shù)據(jù)頁中位置的方式。非聚集索引比聚集索引層次多,添加記錄不會(huì)引起數(shù)據(jù)順序的重組。在有大量不同數(shù)據(jù)的列上建立非聚集索引,可以提高數(shù)據(jù)的查詢和修改速度。

在對(duì)聚集索引列查詢時(shí),聚集索引的速度要比非聚集索引速度快。

在對(duì)聚集索引列排序時(shí),聚集索引的速度要比非聚集索引速度快。但是如果數(shù)據(jù)量比較大時(shí),如10萬以上,則二者的速度差別不明顯。

3.1 聚集索引和非聚集的建立原則

在創(chuàng)建索引時(shí)要做到三個(gè)適當(dāng),即在適當(dāng)?shù)谋砩稀⑦m當(dāng)?shù)牧猩蟿?chuàng)建適當(dāng)數(shù)量的索引。雖然這可以通過一句話來概括優(yōu)化的索引的 基本準(zhǔn)則,但是要做到這一點(diǎn)的話,需要做出很大的努力。具體的來說,要做到這個(gè)三個(gè)適當(dāng)有如下幾個(gè)要求。

3.1.1根據(jù)表的大小來創(chuàng)建索引。

雖然給表創(chuàng)建索引,可以提高查詢的效率。但是需要注意的是,索引也需要一定的開銷的。為此并不是說給所有的表都創(chuàng)建索引,那么就可以提高數(shù)據(jù)庫(kù)的性能。這個(gè)認(rèn)識(shí)是錯(cuò)誤的。給所有的表都創(chuàng)建了索引,那么其反而會(huì)給數(shù)據(jù)庫(kù)的性能造成負(fù)面的影響。因?yàn)榇藭r(shí)濫用索引的開銷可能已經(jīng)遠(yuǎn)遠(yuǎn)大于由此帶來的性能方面的收益。所以,數(shù)據(jù)庫(kù)管理員首先需要做到,為合適的表來建立索引,而不是為所有的表建立索引。

一般來說,不需要為比較小的表創(chuàng)建索引。因?yàn)榧词菇⒘怂饕湫阅芤膊粫?huì)得到很大的改善。相反索引建立的開銷,如維護(hù)成本等等,要比這個(gè)要大。也就是說,付出的要比得到的多,顯然違反常理。

另外,就是對(duì)于超大的表,也不一定要建立索引。有些表雖然比較大,記錄數(shù)量非常的多。但是此時(shí)為這個(gè)表建立索引并一定的合適。對(duì)于一些超大的表,建立索引有時(shí)候往往不能夠達(dá)到預(yù)計(jì)的效果。而且在大表上建立索引,其索引的開銷要比普通的表大的多。那么到底是否給大表建立索引呢?主要是看兩個(gè)方面的內(nèi)容。首先是需要關(guān)注一下,在這張大表中經(jīng)常需要查詢的記錄數(shù)量。一般來說,如果經(jīng)常需要查詢的數(shù)據(jù)不超過10%到15%的話,那就沒有必要為其建立索引的必要。因?yàn)榇藭r(shí)建立索引的開銷可能要比性能的改善大的多。如果數(shù)據(jù)庫(kù)管理員需要得出一個(gè)比較精確的結(jié)論,那么就需要進(jìn)行測(cè)試分析。

3.1.2根據(jù)列的特征來創(chuàng)建索引

列的特點(diǎn)不同,索引創(chuàng)建的效果也不同。需要了解為哪些列創(chuàng)建索引可以起到事半功倍的效果。同時(shí)也需要了解為哪些列創(chuàng)建索引反而起到的是事倍功半的效果。

索引設(shè)置的是否恰當(dāng),不僅跟數(shù)據(jù)庫(kù)設(shè)計(jì)架構(gòu)有關(guān),而且還跟企業(yè)的經(jīng)濟(jì)業(yè)務(wù)相關(guān)。雖然一開始已經(jīng)做了索引的優(yōu)化工作。但是隨著后來經(jīng)濟(jì)數(shù)據(jù)的增加,這個(gè)索引的效果會(huì)越來越打折扣。所以需要隔一段時(shí)間,對(duì)數(shù)據(jù)庫(kù)的索引進(jìn)行優(yōu)化。該去掉的去掉,該調(diào)整的調(diào)整,以提高數(shù)據(jù)庫(kù)的性能。

3.1.3在一個(gè)表上創(chuàng)建多少索引合適

通常來說,表的索引越多,其查詢的速度也就越快。但是,表的更新速度則會(huì)降低。這主要是因?yàn)楸淼母峦瑫r(shí)也是索引的更新。到底在表中創(chuàng)建多少索引合適,就需要在這個(gè)更新速度與查詢速度之間取得一個(gè)均衡點(diǎn)。如對(duì)于一些數(shù)據(jù)倉(cāng)庫(kù)或者決策型數(shù)據(jù)庫(kù)系統(tǒng),其主要用來進(jìn)行查詢。相關(guān)的記錄往往是在數(shù)據(jù)庫(kù)初始化的時(shí)候?qū)搿4藭r(shí),設(shè)置的索引多一點(diǎn),可以提高數(shù)據(jù)庫(kù)的查詢性能。同時(shí)因?yàn)橛涗洸辉趺锤拢运饕容^多的情況下,也不會(huì)影響到更新的速度。相反,如果那些表中經(jīng)常需要更新記錄,如一些事務(wù)型的應(yīng)用系統(tǒng),數(shù)據(jù)更新操作是家常便飯的事情。此時(shí)如果在一張表中建立過多的索引,則會(huì)影響到更新的速度。由于更新操作比較頻繁,所以對(duì)其的負(fù)面影響,要比查詢效率提升要大的多。此時(shí)就需要限制索引的數(shù)量,只在一些必要的字段上建立索引。

4 索引的不足之處

雖然索引大大提高了查詢速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。

建立索引會(huì)占用磁盤空間的索引文件。一般情況這個(gè)問題不太嚴(yán)重,但如果你在一個(gè)大表上創(chuàng)建了多種組合索引,索引文件的會(huì)膨脹很快。

索引只是提高效率的一個(gè)因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時(shí)間研究建立最優(yōu)秀的索引,或優(yōu)化查詢語句。

5 使用索引時(shí),有以下一些技巧和注意事項(xiàng):
5.1 索引不會(huì)包含有NULL值的列

只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無效的。

所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。

5.2 使用短索引

對(duì)列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度。

例如,如果有一個(gè)CHAR(255)的列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。

短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作。

5.3 索引列排序

MySQL查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。

因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要最好給這些列創(chuàng)建復(fù)合索引。

5.4 like語句操作

一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問題。

like “%aaa%” 不會(huì)使用索引,而like “aaa%”可以使用索引。

5.5 不要在列上進(jìn)行運(yùn)算

select * from users where YEAR(adddate)<2007;

將在每個(gè)行上進(jìn)行運(yùn)算,這將導(dǎo)致索引失效而進(jìn)行全表掃描,因此我們可以改成

select * from users where adddate<‘2007-01-01’;

5.6 不使用NOT IN和<>操作

7 索引的建立時(shí)機(jī)

一般來說,在WHERE和JOIN中出現(xiàn)的列需要建立索引,但也不完全如此,

因?yàn)镸ySQL只對(duì)<,<=,=,>,>=,BETWEEN,IN,以及某些時(shí)候的LIKE才會(huì)使用索引。

因?yàn)樵谝酝ㄅ浞?和_開頭作查詢時(shí),MySQL不會(huì)使用索引。

8 索引的使用

8.1 建立索引

create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);

示例:

alter table table_name ADD INDEX [index_name] (index_col_name,…)

CREATE INDEX paywayid_index ON pay_order_trade (paywayid)

8.2 組合索引

CREATE INDEX idx_example ON table1 (col1 ASC, col2 DESC, col3 ASC)

示例:

ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);

最左前綴:顧名思義,就是最左優(yōu)先,

上例中我們創(chuàng)建了lname_fname_age多列索引,相當(dāng)于創(chuàng)建了(lname)單列索引,(lname,fname)組合索引以及(lname,fname,age)組合索引。

8.3 刪除索引

DROP INDEX index_name ON tbl_name;

alter table table_name drop index index_name;

8.4 刪除主鍵(索引)比較特別:

alter table t_b drop primary key;

8.5 查詢索引(均可)

show index from table_name;

show keys from table_name;

desc table_Name;

9查詢慢分析

9.1 回到開始的慢查詢

根據(jù)最左匹配原則,最開始的sql語句的索引應(yīng)該是status、operator_id、type、operate_time的聯(lián)合索引;其中status、operator_id、type的順序可以顛倒,所以我才會(huì)說,把這個(gè)表的所有相關(guān)查詢都找到,會(huì)綜合分析;比如還有如下查詢:

select * from task where status = 0 and type = 12 limit 10;
select count(*) from task where status = 0 ;

那么索引建立成(status,type,operator_id,operate_time)就是非常正確的,因?yàn)榭梢愿采w到所有情況。這個(gè)就是利用了索引的最左匹配的原則

9.2 查詢優(yōu)化神器 – explain命令

關(guān)于explain命令相信大家并不陌生,具體用法和字段含義可以參考官網(wǎng)explain-output,這里需要強(qiáng)調(diào)rows是核心指標(biāo),絕大部分rows小的語句執(zhí)行一定很快(有例外,下面會(huì)講到)。所以優(yōu)化語句基本上都是在優(yōu)化rows。

9.3 慢查詢優(yōu)化基本步驟

  1. 先運(yùn)行看看是否真的很慢,注意設(shè)置SQL_NO_CACHE
  2. where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應(yīng)用到表中返回的記錄數(shù)最小的表開始查起,單表每個(gè)字段分別查詢,看哪個(gè)字段的區(qū)分度最高
  3. explain查看執(zhí)行計(jì)劃,是否與1預(yù)期一致(從鎖定記錄較少的表開始查詢)
  4. order by limit 形式的sql語句讓排序的表優(yōu)先查
  5. 了解業(yè)務(wù)方使用場(chǎng)景
  6. 加索引時(shí)參照建索引的幾大原則
  7. 觀察結(jié)果,不符合預(yù)期繼續(xù)從0分析

索引的優(yōu)化方法

1,何時(shí)使用聚簇索引或非聚簇索引:

動(dòng)作描述

使用聚集索引

使用非聚集索引

列經(jīng)常被分組排序

應(yīng)

應(yīng)

返回某范圍內(nèi)的數(shù)據(jù)

應(yīng)

不應(yīng)

一個(gè)或極少不同值

不應(yīng)

不應(yīng)

小數(shù)目的不同值

應(yīng)

不應(yīng)

大數(shù)目的不同值

不應(yīng)

應(yīng)

頻繁更新的列

不應(yīng)

應(yīng)

外鍵列

應(yīng)

應(yīng)

主鍵列

應(yīng)

應(yīng)

頻繁修改索引列

不應(yīng)

應(yīng)

2,索引不會(huì)包含有NULL值的列:只要列中包含有NULL值,都將不會(huì)被包含在索引中,組合索引中只要有一列有NULL值,那么這一列對(duì)于此條組合索引就是無效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí),不要讓索引字段的默認(rèn)值為NULL。

3,使用短索引:假設(shè),如果有一個(gè)數(shù)據(jù)類型為CHAR(255)的列,在前10個(gè)或20個(gè)字符內(nèi),絕大部分?jǐn)?shù)據(jù)的值是唯一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省I/O操作。

4,索引列排序:MySQL查詢只使用一個(gè)索引,因此如果WHERE子句中已經(jīng)使用了索引的話,那么ORDER BY中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下,不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要,最好給這些列也創(chuàng)建組合索引。

5,LIKE語句操作:一般情況下,不建議使用LIKE操作;如果非使用不可,如何使用也是一個(gè)研究的課題。LIKE “%aaaaa%”不會(huì)使用索引,但是LIKE “aaa%”卻可以使用索引。

6,不要在索引列上進(jìn)行運(yùn)算:在建立索引的原則中,提到了索引列不能進(jìn)行運(yùn)算,這里就不再贅述了。

mysql索引失效情況

1、最佳左前綴原則——如果索引了多列,要遵守最左前綴原則。指的是查詢要從索引的最左前列開始并且不跳過索引中的列。

前提條件:表中已添加復(fù)合索引(username,password,age)

分析:該查詢?nèi)鄙賣sername,查詢條件復(fù)合索引最左側(cè)username缺少,違反了最佳左前綴原則,導(dǎo)致索引失效,變?yōu)锳LL,全表掃描

分析:查詢條件缺少username,password,查詢條件復(fù)合索引最左側(cè)username,password缺少,違反了最佳左前綴原則,導(dǎo)致索引失效,變?yōu)锳LL,全表掃描

分析:該查詢只有一個(gè)username條件,根據(jù)最佳左前綴原則索引能夠被使用到,但是是部分使用

2、不在索引列上做任何操作(計(jì)算,函數(shù),(自動(dòng)或者手動(dòng))類型裝換),會(huì)導(dǎo)致索引失效而導(dǎo)致全表掃描

分析:第一個(gè)圖索引列不使用函數(shù),遵循左前綴原則,能夠使用索引。第二張圖索引列上使用了函數(shù),即使遵循左前綴原則,索引還是失效

3、存儲(chǔ)引擎不能使用索引中范圍條件右邊的列,范圍之后索引失效。(< ,> between and)

分析:圖一索引全部使用到。圖二索引使用到username和age,但是username是使用索引檢索,而age著重索引排序,這時(shí)age為范圍查找,password索引將失效

4、mysql使用不等于(!= 或者<>)的時(shí)候,無法使用索引,會(huì)導(dǎo)致索引失效

5、mysql中使用is not null 或者 is null會(huì)導(dǎo)致無法使用索引

分析:對(duì)username列做了普通索引,查詢帶is not null,結(jié)果索引不生效

6、mysql中l(wèi)ike查詢是以%開頭,索引會(huì)失效變成全表掃描,覆蓋索引。

分析:對(duì)username列做了普通索引,以%開頭進(jìn)行查詢,結(jié)果索引失效被覆蓋

7、mysql中,字符串不加單引號(hào)索引會(huì)失效。正確寫法:select * from t_user where username = ‘lujin’;

8、mysql中,如果條件中有or,即使其中有條件帶索引也不會(huì)使用(這也是為什么盡量少用or的原因)。要想使用or,又想讓索引生效,只能將or條件中的每個(gè)列都加上索引

9、如果mysql使用全表掃描要比使用索引快,則不會(huì)使用到索引

參考:

https://blog.csdn.net/fly910905/article/details/78690074
https://tech.meituan.com/2014/06/30/mysql-index.html
https://segmentfault.com/a/1190000015416513
https://www.cnblogs.com/Jessy/p/3543063.html
https://blog.csdn.net/qq_34258346/article/details/80272198

總結(jié)

以上是生活随笔為你收集整理的sql索引的建立与使用_sqlserver创建索引语句(廖雪峰的官方网站)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。