【SQL SERVER】索引

来源:https://www.cnblogs.com/WilsonPan/archive/2020/04/04/12625364.html
-Advertisement-
Play Games

在做開發過程中經常會接觸資料庫索引,不只是DBA才需要知道索引知識,瞭解索引可以讓我們寫出更高質量代碼。簡單介紹索引的概述,聚集索引,非聚集索引,唯一索引,複合索引,篩選索引使用及註意事項 ...


在做開發過程中經常會接觸資料庫索引,不只是DBA才需要知道索引知識,瞭解索引可以讓我們寫出更高質量代碼。

  1. 索引概述
  2. 聚集索引
  3. 非聚集索引
  4. 唯一索引
  5. 篩選索引
  6. 非聚集索引包含列

索引概述

       索引的存在主要為了提高數據檢索速度,設計高效的索引對於獲得良好的資料庫和應用程式性能極為重要。

       索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定信息,就像平常我們用的新華字典的目錄,假如新華字典沒有目錄有找一個字就必須從第一頁一直翻到最後一頁,這是多麼令人絕望的事情。

  索引是占有而外空間,是一種典型的空間換時間的做法,所以對待索引必須要保持敬畏之心,要建立在經常篩選的條件上,查詢數據要時刻想著利用索引,竟然都花額外空間存儲索引,不能讓它白白浪費掉。

 

聚集索引

聚集索引基於數據行的鍵值在表內排序和存儲這些數據行。 每個表只能有一個聚集索引,因為數據行本身只能按一個順序存儲。  

簡單來說就是聚集索引和數據的存放順序是一致的,聚集索引葉節點就是數據。

創建準則

1. 定義聚集索引鍵時使用的列越少越好

2. 唯一或包含許多不重覆的值(若創建聚集索引時沒使用唯一屬性,SQL Server會自動添加一個4位元組的唯一標識列)

3. 經常需要順序訪問數據

4. 經常用於對錶中檢索到的數據進行排序

5. 列大小不超過900位元組

適合使用聚集索引情況

1. 使用運算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值

2. 返回大型結果集

3. 使用 JOIN 子句;一般情況下,使用該子句的是外鍵列

4. 使用 ORDER BY 或 GROUP BY 排序/分組數據(因為分組數據也是要先排序)

不適合使用聚集索引情況

1. 頻繁更改的列,每次更改都會導致索引頁不斷重新構建。

2. 若幹列或若幹大型列的組合,每次構建排序需要大量計算

TSQL創建聚集索引

--唯一的聚集索引
CREATE UNIQUE CLUSTERED INDEX [IX_TableName_Name] ON [dbo].[TableName] ([FieldName] ASC)

--不唯一的聚集索引
CREATE CLUSTERED INDEX [IX_TableName_Name] ON [dbo].[TableName] ([FieldName] ASC)

 

非聚集索引

非聚集索引包含索引鍵值和指向表數據存儲位置的行定位器。 可以對錶或索引視圖創建多個非聚集索引。 通常,設計非聚集索引是為改善經常使用的、沒有建立聚集索引的查詢的性能。

簡單來說不是聚集索引的就是非聚集索引。額,好像沒解釋一樣。。。非聚集索引的葉節點是定位器。

創建準則

1. 不超過1700位元組(其他文檔說是900位元組,我測試SQL Server是1700位元組)

2. 避免添加不必要的列,因為增加索引維護成本

3. 包含許多不重覆的值,這樣才能更好利用索引查詢效率

4. 列的長度儘可能小

適合使用非聚集索引情況

1. 使用 JOIN 或 GROUP BY 子句

2. 不返回大型結果集的查詢

3. 經常包含在查詢的搜索條件中的列

不適合使用非聚集索引情況

1. 列的重覆值較少

2. 不是經常查詢的搜索條件的列

3. 列的長度過長,因為增加索引維護成本

聚集索引與非聚集索引區別(知識有限,未必全,希望補充)

1. 聚集索引是按物理順序排列,非聚集索引邏輯順序排列

2. 聚集索引一個表只能有一個,非聚集索引可以多個

3. 聚集索引的葉節點是數據,非聚集索引的葉節點是定位器

4. 聚集索引不能附加信息,非聚集索引可以包含附加信息

TSQL創建非聚集索引

CREATE INDEX IX_TableName_FieldName ON DataTable(FieldName DESC)

 

唯一索引

唯一索引能夠保證索引鍵中不包含重覆的值,從而使表中的每一行從某種方式上具有唯一性。 只有當唯一性是數據本身的特征時,指定唯一索引才有意義。

保證索引鍵中不包含重覆的值(包含NULL值)

創建準則

 1. 只有需要保證數據唯一性的情況下才使用

適合使用唯一索引情況

1. 需要保證數據唯一性

不適合使用唯一索引情況 

1. 不需要保證數據唯一性

TSQL創建唯一索引

CREATE UNIQUE INDEX IX_TableName_FieldName ON DataTable(FieldName ASC) 

 

篩選索引

 篩選索引是一種經過優化的非聚集索引,尤其適用於涵蓋從定義完善的數據子集中選擇數據的查詢。 篩選索引使用篩選謂詞對錶中的部分行進行索引。

只把符合條件的數據做索引,相當於在一個表的子集做索引。從而達到下麵幾個好處

1. 提高了查詢性能 ,因為索引頁的數據比全表索引小

2. 減少索引維護開銷,因為只有符合條件才會對索引頁維護

3. 減少索引存儲開銷,道理跟上面一樣

創建準則

1. 篩選的條件必須是明確的值

2. 通常來說經常查詢出現的條件跟過濾條件符合

3. 經常檢索的都是數據的子集

適合使用篩選索引情況

1. 經常篩選表的子集數據,例如通常我們只查詢有效的訂單,無效的訂單很少查,或者基本不查,這種情況適合建立篩選索引

2. 只查最近數據,例如記錄只查最近一個月,可以通過定期在資料庫空閑的時重新維護篩選索引達到加快查詢效率

不適合使用篩選索引情況

1. 經常查詢條件包含篩選值外,這樣導致走全表掃描(前提沒其他索引覆蓋到)

2. 查詢條件不固定

TSQL創建唯一索引

CREATE INDEX IX_TableName_FieldName ON [dbo].[TableName](FieldName ASC)  where State > 1

 

非聚集索引包含列

 通過將非鍵列添加到非聚集索引的葉級,擴展非聚集索引的功能。 通過包含非鍵列,可以創建覆蓋更多查詢的非聚集索引

通過把包含的列同時維護在索引頁,達到當查詢的數據都包含在索引中的數據的時候,因為在索引頁找到所有數據,就不需要訪問表的數據頁,從而減少I/O操作,這種通常稱為“覆蓋查詢”

創建準則

1. 必須至少定義一個鍵列

2. 在 CREATE INDEX 語句的 INCLUDE 子句中定義非鍵列

3. 只能對錶或索引視圖的非聚集索引定義非鍵列

4. 允許除 text、 ntext和 image之外的所有數據類型

5. 精確或不精確的確定性計算列都可以是包含列

6. 不能同時在 INCLUDE 列表和鍵列列表中指定列名

7. INCLUDE 列表中的列名不能重覆

8. 索引鍵列(不包括非鍵)必須遵守現有索引大小的限制

9. 所有非鍵列的總大小隻受 INCLUDE 子句中所指定列的大小限制;例如, varchar(max) 列限製為 2 GB

適合使用非聚集索引包含列

1. 篩選的列是索引鍵 && 查詢的列都是包含的列

不適合使用非聚集索引包含列

2. 篩選的列不是索引鍵  ||  查詢的列有不在包含列中的

TSQL創建篩選索引

CREATE  INDEX IX_TableName_FieldName ON DataTable(Field1 ASC) INCLUDE(Field2)

轉發請標明出處: https://www.cnblogs.com/WilsonPan/p/12625364.html

參考文章

SQL Server 索引體繫結構和設計指南 - SQL Server | Microsoft Docs 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有時我們臨時需要一個 JSON 字元串,直接拼接肯定不是好方法,但又懶得去定義一個類,這是用 就會非常的方便。 但是在 中添加數組卻經常被坑。 輸出結果: 非常正確,但如果把 換成 就不對了。 這麼寫會報: Could not determine JSON object type for type ...
  • 0、概述 先瞭解下https是個啥: https://www.bilibili.com/video/BV1j7411H7vV so!只要給我們的web伺服器配置一個證書就行了,證書可以買,也可以用免費的Let's Encrypt,此證書提供商是多個牛X大公司為了推進全球https化搞出來的,所以不用 ...
  • HTTP Method 較為簡單,我們常用的習慣如下: 一般查詢我們都會使用 GET 方法, 創建新的記錄使用 POST 方法 更新已有數據使用 PUT 方法 更新已有數據部分屬性使用 PATCH 方法 刪除已有數據使用 DELETE 方法 下麵來詳細介紹一下常用的 HTTP 狀態碼 1xx 1xx ...
  • 最近是真的比較閑,花了點時間算是把我自己的微博庫的 nuget 包的坑填上了(https://github.com/h82258652/HN.Social.Weibo 歡迎大佬來 Star)。dino 大佬也一直忽悠我弄動畫,可惜我沒啥藝術細胞而且 Composition API 也不太熟悉,就只能 ...
  • Xamarin.Forms客戶端第一版 作為TerminalMACS的一個子進程模塊,目前完成第一版:讀取展示手機基本信息、聯繫人信息、應用程式本地化。 1. 功能簡介 2. 詳細功能說明 3. 關於TerminalMACS 1. 功能簡介 1.1. 讀取手機基本信息 主要使用Xamarin.Ess ...
  • 通過VPN訪問Google時,Google仍舊無法打開,但是能訪問部分網站。這是什麼情況? 顯然能夠訪問部分網站,說明網路是正常的,經過不停的測試,我發現只要是支持HTTPS協議的網站都無法訪問,腦袋靈機一動,是不是跟HTTPS的埠443有關,檢查之後,發現果真VPN服務端的443埠沒有在防火牆 ...
  • Shell腳本殺掉除自己外的舊進程 在寫後臺Shell腳本的時候,這是比較常見的一個需求。比如之前運行了一個叫做a.sh的腳本在後臺運行,後來更新了a.sh腳本想重新運行,但卻不想手動殺掉已經存在的後臺a.sh進程。 命令其實非常簡單: 其中 是篩選出除腳本自己之外的舊進程的PID。 這裡的 做了些 ...
  • Oracle的存儲結構分為:物理存儲結構和邏輯存儲結構。 一、物理存儲結構:指硬碟上存在的文件 數據文件(data file) 一個資料庫可以由多個數據文件組成的,數據文件是真正存放資料庫數據的。一個數據文件就是一個操作系統文件。資料庫的對象(表和索引)物理上是被存放在數據文件中的。當我們要查詢一個 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...