聚簇索引并不是一種單獨的索引,而是一種數據存儲方式.具體的細節依賴于其實現方式,但Innodb的聚簇索引實際上在同一個結構保存了B-Tree索引和數據行
當表有聚簇索引時,它的數據行實際上存放在索引的葉子頁中.術語"聚簇"表示數據行和相鄰的鍵值緊湊的存儲在一起(這并非總成立)**.因為無法同時把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引(不過,覆蓋索引可以模擬多個聚簇索引的情況)**
因為是存儲引擎負責實現索引,因此不是所有的存儲引擎都支持聚簇索引.
下面展示聚簇索引中的記錄是如何存放.注意到,葉子頁包含了行的全部數據,但是節點頁只包含了索引列
在這個案列中,索引列包含的是整數值

聚簇索引的數據分布
一些數據庫允許選擇哪個索引作為聚簇索引,但是到現在沒有那個mysql內建的存儲引擎支持這一點.Innodb將通過主鍵聚集數據,這也就是說上圖中的"被索引的列"就是主鍵列
如果沒有定義主鍵,Innodb會選擇一個唯一的非空索引代替.如果沒有這樣的索引,Innodb會隱式定義一個主鍵來作為聚簇索引.Innodb只聚集在同一個頁面中的記錄.包含相鄰鍵值的頁面可能會相距甚遠
聚簇索引可能對性能有幫助,但也可能導致嚴重的性能問題.所以需要仔細的考慮聚簇索引,尤其是將表的存儲引擎從Innodb改成其他存儲引擎
聚簇索引有一些優點
* 可以把相關數據保存在一起.例如實現電子郵箱時,可以根據用戶ID來聚集數據,這樣只需要從磁盤讀取少量的數據頁就能獲取某個用戶的全部郵件.如果沒有使用聚簇索引,者每封郵件都可能導致一次磁盤IO
* 數據訪問更快.聚簇索引將索引和數據保存在一個B-Tree中,因此從聚簇索引中獲取數據通常比在非聚簇索引中查找要快
* 使用覆蓋索引掃描的查詢可以直接使用頁節點的主鍵值
如果在設計表和查詢時充分利用到上面的優點,那就能極大的提升性能.同時,聚簇索引也有一些缺點
* 聚簇數據最大限度的提高了I/O密集型應用的性能,但如果數據全部都放在內存中,則訪問的順序就沒有那么重要了,聚簇索引也就沒有什么優勢了
* 插入速度嚴重依賴于插入順序.按照主鍵的順序插入是加載數據到Innodb表中速度最快的方式.但如果不是按照主鍵順序加載數據,那么在加載完成后最好使用OPTIMIZE TABLE命令重新組織下表
* 更新聚簇索引的表在插入新行,或者主鍵被更新導致需要移動行的時候,可能面臨頁分裂的問題.當行的主鍵值要求必須將這一行插入到某個已滿的頁中時,存儲引擎會將該頁分裂成兩個頁面來容納該行,這就是一次分裂操作.頁分裂會導致表占用更多的磁盤空間
* 聚簇索引可能導致全表掃描變慢,尤其是行比較稀疏,或者由于頁分裂導致數據存儲不連續的時候
* 二級索引(非聚簇索引)可能比想象的更大,因為在二級索引的葉子節點包含了引用行的主鍵列
* 二級索引訪問需要進行兩次索引查找,而不是一次
**為什么要進行2次索引查找?**
**二級索引保存的"行指針",要記住,二級索引葉子節點保存的不是指向行的物理位置的指針,而是行的主鍵值**
**這意味著通過二級索引查找行,存儲引擎需要找到二級索引的葉子節點獲得對應的主鍵值,然后根據這個值去聚簇索引中查找對應的行.這里做了重復工作:兩次B-Tree查找而不是一次(并不是所有的非聚簇索引都能夠做到一次索引查詢就能找到行.當行更新的時候可能無法存儲在原來的位置,這會導致表中出現行的碎片化或者移動行并在原位置保存"向前指針".這兩種情況都會導致在查找行時需要更多的工作).對應Innodb,自適應hash能夠減少這樣的重復工作**
- 書列表
- laravel框架關鍵技術
- 第一章 組件化開發與composer使用
- 簡介
- composer
- 添加路由組件
- 添加控制器模塊
- 添加模型組件
- 添加視圖組件
- 第三章 laravel框架中常用的php語法
- 匿名函數
- 文件包含
- 魔術方法
- 魔術常量
- 反射
- 后期靜態綁定
- traits
- 第四章 laravel框架中使用的HTTP協議基礎
- HTTP協議
- 數據庫
- 數據遷移
- 第六章 laravel框架中的設計模式
- IOC模式
- php核心技術與最佳實踐
- 第一章面向對象核心
- 反射
- 簡單ORM
- 異常和錯誤
- 接口
- 第二章,面向對象設計
- 設計原則
- 單一職責
- 接口隔離
- 開放封閉
- 替換原則
- 依賴倒置
- linux是怎么寫的呢?
- 第三章 正則表達
- 認識正則
- 第四章 php網絡技術應用
- HTTP協議詳解
- php和http相關函數
- 垃圾信息防御措施
- 現代操作系統
- 引論
- sql必知必會
- 限制結果
- 按位置排序
- where求職順序
- IN操作符
- like
- 函數
- group by
- 組合查詢
- 插入檢索出的數據
- 視圖
- 高性能mysql
- 第一章節 mysql架構與歷史
- mysql架構邏輯圖
- 連接與管理
- 優化與運行
- 讀寫鎖
- 鎖粒度
- 表鎖(table lock)
- 行級鎖(row lock)
- ACID
- 隔離級別
- 死鎖
- 隱式和顯式鎖定
- 多版本并發控制
- Innodb概覽
- 第四章節 Schema與數據類型優化
- 選擇優化的數據類型
- 日期和時間類型
- 標識列
- 特殊類型數據
- 表設計中的缺陷
- 范式
- 計數器表
- 第五章 創建高性能索引
- 索引基礎
- 索引類型
- 索引的優點
- 高性能索引策略
- 選擇合適的索引列順序
- 聚簇索引
- 順序的主鍵什么時候會造成更壞的后果
- 覆蓋索引
- 使用索引掃描來做排序
- 壓縮索引
- 冗余和重復索引
- 索引和鎖
- 支持多種過濾條件
- 什么是范圍條件
- 優化排序
- 維護索引和表
- 表損壞
- 減少索引和數據的碎片
- 第六章 查詢性能優化
- 掃描的行數和訪問類型
- 重構查詢方式
- 查詢執行的基礎
- 重構-改善既有代碼設計
- 第一章-重構
- 什么是重構
- 第一個案列
- 重構第一步
- 王垠博客
- 多態取代價格相關邏輯