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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于索引的相关 day45

發布時間:2025/3/15 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于索引的相关 day45 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

mysql數據庫索引相關

一 介紹

什么是索引?

索引在MySQL中也叫做“鍵”,是存儲引擎用于快速找到記錄的一種數據結構。索引對于良好的性能
非常關鍵,尤其是當表中的數據量越來越大時,索引對于性能的影響愈發重要。
索引優化應該是對查詢性能優化最有效的手段了。索引能夠輕易將查詢性能提高好幾個數量級。
索引相當于字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。

(建索引是讓mysql提供的一種數據結構)

索引相關見解

索引是應用程序設計和開發的一個重要方面。若索引太多,應用程序的性能可能會受到影響。而索引太少,對查詢性能又會產生影響,要找到一個平衡點,這對應用程序的性能至關重要。一些開發人員總是在事后才想起添加索引----我一直認為,這源于一種錯誤的開發模式。如果知道數據的使用,從一開始就應該在需要處添加索引。開發人員往往對數據庫的使用停留在應用的層面,比如編寫SQL語句、存儲過程之類,他們甚至可能不知道索引的存在,或認為事后讓相關DBA加上即可。DBA往往不夠了解業務的數據流,而添加索引需要通過監控大量的SQL語句進而從中找到問題,這個步驟所需的時間肯定是遠大于初始添加索引所需的時間,并且可能會遺漏一部分的索引。當然索引也并不是越多越好,我曾經遇到過這樣一個問題:某臺MySQL服務器iostat顯示磁盤使用率一直處于100%,經過分析后發現是由于開發人員添加了太多的索引,在刪除一些不必要的索引之后,磁盤使用率馬上下降為20%。可見索引的添加也是非常有技術含量的。

二、索引的原理

索引的目的在于提高查詢效率。

本質:通過不斷的縮小想要獲取數據的范圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數據。

三、 索引的數據結構

需要這種數據結構能夠做些什么,其實很簡單,那就是:每次查找數據時把磁盤IO次數控制在一個很小的數量級,最好是常數數量級。那么我們就想到如果一個高度可控的多路搜索樹是否能滿足需求呢?就這樣,b+樹應運而生(B+樹是通過二叉查找樹,再由平衡二叉樹,B樹演化而來)。

如上圖,是一顆b+樹,關于b+樹的定義可以參見B+樹,這里只說一些重點,淺藍色的塊我們稱之為一個磁盤塊,可以看到每個磁盤塊包含幾個數據項(深藍色所示)和指針(黃色所示),如磁盤塊1包含數據項17和35,包含指針P1、P2、P3,P1表示小于17的磁盤塊,P2表示在17和35之間的磁盤塊,P3表示大于35的磁盤塊。真實的數據存在于葉子節點即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節點只不存儲真實的數據,只存儲指引搜索方向的數據項,如17、35并不真實存在于數據表中。

b+樹性質

1、索引字段要盡量的小

2、索引的最左匹配特性

三、常見的索引

索引分類:

1、普通索引INDEX:加速查找

  唯一索引:
2、-主鍵索引PRIMARY KEY:加速查找+約束(不為空、不能重復)
3、-唯一索引UNIQUE:加速查找+約束(不能重復)
4、-組合索引

  組合索引是將n個列組合成一個索引

5、聯合索引:

??? -PRIMARY KEY(id,name):聯合主鍵索引
??? -UNIQUE(id,name):聯合唯一索引
??? -INDEX(id,name):聯合普通索引

除此之外還有全文索引,即FULLTEXT,但其實對于全文搜索,我們并不會使用MySQL自帶的該索引,而是會選擇第三方軟件如Sphinx,專門來做全文搜索。

二、索引類型

  索引主要包括hash和btree兩大類型,我們在創建索引時可以為其指定索引類型。其中hash類型的索引:查詢單條快,范圍查詢慢;btree類型的索引:b+樹,層數越多,數據量指數級增長(我們就用它,因為innodb默認支持它)

#不同的存儲引擎支持的索引類型也不一樣 InnoDB 支持事務,支持行級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引; MyISAM 不支持事務,支持表級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引; Memory 不支持事務,支持表級別鎖定,支持 B-tree、Hash 等索引,不支持 Full-text 索引; NDB 支持事務,支持行級別鎖定,支持 Hash 索引,不支持 B-tree、Full-text 等索引; Archive 不支持事務,支持表級別鎖定,不支持 B-tree、Hash、Full-text 等索引;

三、創建與刪除索引

1、在創建表時創建索引

create table t1(
??? id int,
??? name char(5),
??? age int,
??? unique key uni_name(name),??? # uni_name 為索引名 ??? ?
??? index index_age(age),???????? # index_age 為索引名,不需要key
??? primary key(id)?????????????? # primary 不需要起索引名,起了也不顯示 ?? ?
???? );

2、創建完表后為其添加索引

3、刪除索引

?

drop index indx_id on t3;alter table t3 drop primary key;

  上述第一個刪除語法中,因primary key 沒有名字,所以刪除方式為:drop index ‘primary’ on t3,其他有名字的索引刪除方式為:drop index 索引名 on 表名

?

四、測試索引

  按照如下sql語句創建表s1,后續所有測試均基于此表:

#1. 準備表 create table s1( id int, name varchar(20), gender char(6), email varchar(50) );#2. 創建存儲過程,實現批量插入記錄 delimiter $$ #聲明存儲過程的結束符號為$$ create procedure auto_insert1() BEGINdeclare i int default 1;while(i<3000000)doinsert into s1 values(i,'egon','male',concat('egon',i,'@oldboy'));set i=i+1;end while; END$$ #$$結束 delimiter ; #重新聲明分號為結束符號#3. 查看存儲過程 show create procedure auto_insert1\G #4. 調用存儲過程 call auto_insert1();

1、加索引可以加快查詢效率,但是會降低寫的效率

?五、正確使用索引

  但我們必須知道,并不是說我們創建了索引就一定會加快查詢速度,若想利用索引達到預想的提高查詢速度的效果,我們在添加索引時,必須遵循以下問題。

1、范圍問題,或者說條件不明確,條件中出現這些符號或關鍵字:>、>=、<、<=、!= 、between...and...、like

  大于 小于

?

不等于

between...and

?

?like

?

?2、盡量選擇區分度高的字段作為索引,區分度是指的字段中數據的重復性,越重復,區分度變低

?

我們編寫存儲過程為表s1批量添加記錄,name字段的值均為egon,也就是說name這個字段的區分度很低(gender字段也是一樣的,我們稍后再搭理它)回憶b+樹的結構,查詢的速度與樹的高度成反比,要想將樹的高低控制的很低,需要保證:在某一層內數據項均是按照從左到右,從小到大的順序依次排開,即左1<左2<左3<...而對于區分度低的字段,無法找到大小關系,因為值都是相等的,毫無疑問,還想要用b+樹存放這些等值的數據,只能增加樹的高度,字段的區分度越低,則樹的高度越高。極端的情況,索引字段的值都一樣,
那么b+樹幾乎成了一根棍。本例中就是這種極端的情況,name字段所有的值均為'egon'#現在我們得出一個結論:為區分度低的字段建立索引,索引樹的高度會很高,然而這具體會帶來什么影響呢???#1:如果條件是name='xxxx',那么肯定是可以第一時間判斷出'xxxx'是不在索引樹中的(因為樹中所有的值均為'egon’),所以查詢速度很快#2:如果條件正好是name='egon',查詢時,我們永遠無法從樹的某個位置得到一個明確的范圍,只能往下找,往下找,往下找。。。這與全表掃描的IO次數沒有多大區別,所以速度很慢

?

3、索引字段不可以參與計算

?\

?

?

??在左邊條件成立但是索引字段的區分度低的情況下(name與gender均屬于這種情況),會依次往右找到一個區分度高的索引字段,加速查詢

?

?

??在左邊條件成立但是索引字段的區分度低的情況下(name與gender均屬于這種情況),會依次往右找到一個區分度高的索引字段,加速查詢

?經過分析,在條件為name='egon' and gender='male' and id>333 and email='xxx'的情況下,我們完全沒必要為前三個條件的字段加索引,因為只能用上email字段的索引,前三個字段的索引反而會降低我們的查詢效率。

?5、最左前綴匹配原則,非常重要的原則,對于組合索引mysql會一直向右匹配直到遇到范圍查詢(>、<、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的順序可以任意調整。

6、其他情況

- 使用函數select * from tb1 where reverse(email) = 'egon';- 類型不一致如果列是字符串類型,傳入條件是必須用引號引起來,不然...select * from tb1 where email = 999;#排序條件為索引,則select字段必須也是索引字段,否則無法命中 - order byselect name from s1 order by email desc;當根據索引排序時候,select查詢的字段如果不是索引,則速度仍然很慢select email from s1 order by email desc;特別的:如果對主鍵排序,則還是速度很快:select * from tb1 order by nid desc;- 組合索引最左前綴如果組合索引為:(name,email)name and email -- 命中索引name -- 命中索引email -- 未命中索引- count(1)或count(列)代替count(*)在mysql中沒有差別了- create index xxxx on tb(title(19)) #text類型,必須制定長度 - 避免使用select * - count(1)或count(列) 代替 count(*) - 創建表時盡量時 char 代替 varchar - 表的字段順序固定長度的字段優先 - 組合索引代替多個單列索引(經常使用多個條件查詢時) - 盡量使用短索引 - 使用連接(JOIN)來代替子查詢(Sub-Queries) - 連表時注意條件類型需一致 - 索引散列值(重復少)不適合建索引,例:性別不適合

六、索引合并與覆蓋

1、索引合并

#覆蓋索引:- 所有字段(條件的,查詢結果的等)都是索引字段http://blog.itpub.net/22664653/viewspace-774667/#分析 select age from s1 where id=123 and name = 'egon'; #id字段有索引,但是name字段沒有索引 該sql命中了索引,但未覆蓋全部。 利用id=123到索引的數據結構中定位到了id字段,但是仍要判斷name字段,但是name字段沒有索引,而且查詢結果的字段age也沒有索引 最牛逼的情況是,索引字段覆蓋了所有,那全程通過索引來加速查詢以及獲取結果就ok了

七、查詢優化神器explain

  關于explain命令相信大家并不陌生,具體用法和字段含義可以參考官網explain-output,這里需要強調rows是核心指標,絕大部分rows小的語句執行一定很快(有例外,下面會講到)。所以優化語句基本上都是在優化rows。

轉載于:https://www.cnblogs.com/xiaoluoboer/p/8075911.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的关于索引的相关 day45的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。