軟體開發人員真的瞭解SQL索引嗎(聚集索引)
大家可能認為這個問題難度不大,認為太熟悉了,也許不會感興趣,但你真能說清楚嗎?其實要想說明白這兩者的差別也不是三兩句就說的清的,那天我也是覺的這問題太泛了,就隨便說了其中的兩個區別:
第一:聚集索引一個表只能有一個,而非聚集索引一個表可以存在多個,這個跟沒問題沒差別,一般人都知道。
第二:聚集索引儲存記錄是物理上連續存在,而非聚集索引是邏輯上的連續,物理儲存並不連續,這個大家也都知道。
上面的兩點從大的方面講都是講的通的,後面我們繼續探討,舉一個實際點的例子,一個學生表student,裡面是學生號id,學生姓名,學生所在城市ID,學生成績(總分),
問:如果想按姓名查詢,如何做優化?
答:在姓名欄位上建立索引。
問:建立什麼型別的索引?
答:建立非聚集索引。
問:如果想按學生的學分範圍來查詢呢,例如查詢得分在60-90的?
答:在學分欄位上建立聚集索引?
問:為什麼?
答:一般有範圍查詢的需求,可以考慮在此欄位上建立聚集索引。
問:學分有重複性,在學分欄位上建立聚集索引能行嗎?
....沉思,不能建立嗎?之前的專案好像真這樣做過
答:應該可以吧。
問:聚集索引的約束是什麼?
答:唯一性啊?
問:既然是唯一性,那麼學分欄位上還能建立聚集索引嗎?
....再次沉思,應該可以啊,但索引的約束又怎麼說呢?
答:應該可以的,以前用過。
我自認為是對資料庫索引知識有一定研究的,但可能是有兩年沒實際接觸SQL的原因,一時還真想不出具有說服力的解釋,朋友們看到這能解答我的問題嗎?
其實上面的我們需要搞清楚以下幾個問題:
第一:聚集索引的約束是唯一性,是否要求欄位也是唯一的呢?
分析:如果認為是的朋友,可能是受系統預設設定的影響,一般我們指定一個表的主鍵,如果這個表之前沒有聚集索引,同時建立主鍵時候沒有強制指定使用非聚集索引,SQL會預設在此欄位上建立一個聚集索引,而主鍵都是唯一的,所以理所當然的認為建立聚集索引的欄位也需要唯一。
結論:聚集索引可以建立在任何一列你想建立的欄位上,這是從理論上講,實際情況並不能隨便指定,否則在效能上會是惡夢。
第二:為什麼聚集索引可以建立在任何一列上,如果此表沒有主鍵約束,即有可能存在重複行資料呢?
粗一看,這還真是和聚集索引的約束相背,但實際情況真可以建立聚集索引,分析其原因是:如果未使用 UNIQUE 屬性建立聚集索引,資料庫引擎將向表自動新增一個四位元組 uniqueifier 列。必要時,資料庫引擎 將向行自動新增一個 uniqueifier 值,使每個鍵唯一。此列和列值供內部使用,使用者不能檢視或訪問。
第三:是不是聚集索引就一定要比非聚集索引效能優呢?
如果想查詢學分在60-90之間的學生的學分以及姓名,在學分上建立聚集索引是否是最優的呢?
答:否。既然只輸出兩列,我們可以在學分以及學生姓名上建立聯合非聚集索引,此時的索引就形成了覆蓋索引,即索引所儲存的內容就是最終輸出的資料,這種索引在比以學分為聚集索引做查詢效能更好。
第四:在資料庫中通過什麼描述聚集索引與非聚集索引的?
索引是通過二叉樹的形式進行描述的,我們可以這樣區分聚集與非聚集索引的區別:聚集索引的葉節點就是最終的資料節點,而非聚集索引的葉節仍然是索引節點,但它有一個指向最終資料的指標。
第五:在主鍵是建立聚集索引的表在資料插入上為什麼比主鍵上建立非聚集索引錶速度要慢?
有了上面第四點的認識,我們分析這個問題就有把握了,在有主鍵的表中插入資料行,由於有主鍵唯一性的約束,所以需要保證插入的資料沒有重複。我們來比較下主鍵為聚集索引和非聚集索引的查詢情況:聚集索引由於索引葉節點就是資料頁,所以如果想檢查主鍵的唯一性,需要遍歷所有資料節點才行,但非聚集索引不同,由於非聚集索引上已經包含了主鍵值,所以查詢主鍵唯一性,只需要遍歷所有的索引頁就行,這比遍歷所有資料行減少了不少IO消耗。這就是為什麼主鍵上建立非聚集索引比主鍵上建立聚集索引在插入資料時要快的真正原因。
好了,講這這些,不知道大家是否真的瞭解SQL的聚焦索引,我也是資料庫新手(從使用時間上來講也不算新了,哈哈),不專業,有什麼不對的地方,希望大家批評指正,下篇我會分析一些資料庫訪問索引的情況,有圖的情況下,也許看的更加明白。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-682263/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server索引 - 非聚集索引SQLServer索引
- mysql關於聚集索引、非聚集索引的總結MySql索引
- 從InnoDB 索引執行簡述 聚集索引和非聚集索引、覆蓋索引、回表、索引下推索引
- 一文總結分析聚集索引、非聚集索引、覆蓋索引的工作原理!索引
- 主鍵索引 (聚集索引) 和普通索引 (輔助索引) 的區別索引
- 神奇的 SQL 之擦肩而過 → 真的用到索引了嗎SQL索引
- 軟體測試真的比不上軟體開發嗎?
- 你真的瞭解“SQL”嗎?《SQL優化最佳實踐》作者帶你重新瞭解SQLSQL優化
- 深入瞭解MySQL的索引MySql索引
- 高併發,你真的瞭解嗎?
- 你真的理解索引嗎?從資料結構層面解析mysql索引原理索引資料結構MySql
- 你真的會使用資料庫的索引嗎?資料庫索引
- SQLSERVER 的主鍵索引真的是物理有序嗎?SQLServer索引
- 【開發必看】你真的瞭解迴流和重繪嗎?
- 你真的瞭解RPC嗎?RPC
- 你真的瞭解@Async嗎?
- ViewStub你真的瞭解嗎View
- 你真的瞭解 Array 嗎?
- 你真的瞭解mongoose嗎?Go
- 你真的瞭解HTAP嗎
- 你真的瞭解URLEncode嗎?
- 開發人員不得不知的MySQL索引和查詢優化MySql索引優化
- Java併發(7)- 你真的瞭解 ReentrantReadWriteLock 嗎?Java
- 你真的瞭解Java記憶體模型JMM嗎?Java記憶體模型
- MYSQL索引為什麼這麼快?瞭解索引的神奇之處MySql索引
- 你真的瞭解前端路由嗎?前端路由
- JavaScript 你真的瞭解this指向嗎JavaScript
- 你真的瞭解過 ConcurrentHashMap 嗎?HashMap
- 淺談sql索引SQL索引
- 掌握4種SQL索引型別,剖析索引原理SQL索引型別
- 軟體定製開發真的比SaaS系統好嗎
- 每個JavaScript開發人員都應該瞭解UnicodeJavaScriptUnicode
- 如何成為更好的軟體開發人員
- 你真的瞭解js運算子嗎JS
- 你真的瞭解npm-scripts嗎?NPM
- 你真的瞭解 Cookie 和 Session 嗎CookieSession
- 你真的瞭解 sync.Once 嗎
- 你真的瞭解深度學習嗎?深度學習
- 你真的瞭解 Cookie 和 Session 嗎?CookieSession