1. 程式人生 > >《T-SQL查詢》讀書筆記Part 3.索引的基本知識

《T-SQL查詢》讀書筆記Part 3.索引的基本知識

索引優化是查詢優化中最重要的一部分,索引是一種用於排序和搜尋的結構,在查詢資料時索引可以減少對I/O的需要;當計劃中的某些元素需要或是可以利用經過排序的資料時,也會減少對排序的需要。某些方面的優化可以適度提高效能,而索引優化經常可以大幅度地提高查詢效能。

一、表和索引的結構

1.1 頁和區

  頁是MSSQL儲存資料的基本單位,大小為8KB,是MSSQL可以讀寫的最小I/O單位。=> 即使只訪問一行,MS SQL也會將整個頁載入到快取,再從換從中讀取資料。

  

  區是由8個物理上連續的頁組成的單元。=> 當表或索引需要更多空間以儲存資料時,MSSQL會為物件分配一個完整的區。

為了使空間分配更有效,SQL Server 不會將所有區分配給包含少量資料的表。MSSQL有兩種型別的區:混合區和統一區,區別詳見參考資料(4)

  

PS:看來MSSQL比較喜歡8這個數字。此外,我們需要了解的就是I/O操作中開銷最大的部分是磁碟臂(Disk Arm)的移動,而真正的磁碟讀寫操作的開銷要小得多;因此,讀取一個頁和讀取整個區所用的時間幾乎一樣長。

1.2 表的組織方式

  堆(Heap)

  堆是不含聚集索引的表(所以只有非聚集索引的表也是堆),因為它的資料不會按照任何順序進行組織,而是按分割槽組隊資料進行組織。=> 當你使用SELECT語句訪問堆表時,MSSQL在執行計劃裡會使用表掃描(Table Scan)

運算子,因為你沒有定義合適的聚集索引。表掃描意味著你必須掃描整張表,不以你表擁有的資料量來衡量。你的資料量越多,操作花費(時間)越長。

在堆中,有一個索引分配對映(IAM)的點陣圖頁用於儲存資料之間的關係,在下圖中,MSSQL維護著指向第一個IAM頁和堆中第一個資料也的內部指標。

  

  這些指標可以在系統檢視sys.system_internals_allocation_units中找到。

  

  B樹

  MSSQL中的所有聚集索引都是按照B樹結構組織的,B樹中的每一頁稱為一個索引節點。每個索引行包含一個鍵值和一個指標。指標指向B樹上的某一中間級頁(比如根節點指向中間級節點中的索引頁)

或葉級索引中的某個資料行(比如中間級索引頁中的某個索引行指向葉子節點中的資料頁)。每級索引中的頁均被連結在雙向連結列表中。資料鏈內的頁和行將按聚集索引鍵值進行排序,聚集索引保證了表格的資料按照索引行的順序排列

    

二、索引的訪問方法

2.1 表掃描/無序聚集索引掃描

  表掃描/無序聚集索引掃描是對錶的所有資料頁進行掃描。下面的查詢就對Orders表(結構化為堆,因此查詢之前需要首先刪除該表的聚集索引)執行表掃描:

  

  執行這個查詢後,通過STATISTICS IO, STATISTICS TIME得到的效能指標如下所示:

-- clear cache
dbcc dropcleanbuffers;
-- statistics io
set statistics io on;
-- statistics time
set statistics time on;

  

  如果該表包含聚集索引,那麼採用的訪問方法將會是無序聚集索引掃描(Clustered Index Scan運算子,其Ordered屬性為False)。下圖展示了優化器為該查詢將生成的執行計劃。

  這裡首先給Orders表加一個聚集索引。

-- add clustered index for Orders
create clustered index idx_cl_od on dbo.Orders(orderdate);

  再次檢視執行計劃,從表掃描變成了聚集索引掃描。這裡可以看到其中已排序這個屬性為False,就關係引擎來說,該運算子不需要返回有序的資料。(即返回任何順序的資料都沒有問題)

  

  執行這個查詢後,通過STATISTICS IO, STATISTICS TIME得到的效能指標如下所示:

  

  可以看到,表掃描和無序聚集索引掃描的查詢效率差不多的。

2.2 無序覆蓋非聚集索引掃描

  無序覆蓋非聚集索引掃描類似於無序聚集索引掃描,覆蓋索引的概念表示非聚集索引包含在查詢中指定的所有列中。MSSQL只需要訪問索引資料就可以找到滿足查詢所需的全部資料。

  這裡我們來看看下面的查詢,假設我們之前在Orders表的orderid列上建立了一個非聚集索引PK_Orders(主鍵),即所有orderid都處於索引的葉級。因此,索引覆蓋了這個查詢。

-- pk_orders
select orderid 
from dbo.Orders;

  其執行計劃如下圖所示:

  

  執行這個查詢後,通過STATISTICS IO, STATISTICS TIME得到的效能指標如下所示:

  

  可以看到,邏輯讀取次數減少了近10倍,而執行時間減少了一半。

2.3 有序聚集索引掃描

  有序聚集索引掃描是針對聚集索引的葉級執行的一種完整掃描,可以確保按照索引順序為下一個運算子返回資料。

  例如,下面的查詢請求按orderdate排序的所有訂單:

-- ordered clustered index scan
select orderid, custid, empid, shipperid, orderdate 
from dbo.Orders
order by orderdate;

  其執行計劃如下圖所示,可以看到這次已排序屬性值變成了True。這就表示,從運算子返回來的資料應該是有序的,而且儲存引擎只能以索引順序掃描。

  

  執行這個查詢後,通過STATISTICS IO, STATISTICS TIME得到的效能指標如下所示:

  

  可以看到,查詢效率和表掃描、無序聚集索引掃描差不多,執行時間略多於前兩者。

參考資料

  

(1)[美] Itzik Ben-Gan 著,成保棟 譯,《Microsoft SQL Server 2008技術內幕:T-SQL查詢》

(4)Microsoft TechNet,《TN 頁和區

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

T-SQL查詢讀書筆記Part 3.索引基本知識

索引優化是查詢優化中最重要的一部分,索引是一種用於排序和搜尋的結構,在查詢資料時索引可以減少對I/O的需要;當計劃中的某些元素需要或是可以利用經過排序的資料時,也會減少對排序的需要。某些方面的優化可以適度提高效能,而索引優化經常可以大幅度地提高查詢效能。 一、表和索引的結構 1.1 頁和區   頁是MS

T-SQL查詢讀書筆記Part 1.邏輯查詢處理知多少

一、關於T-SQL   T-SQL是ANSI和ISO SQL標準的MS SQL擴充套件,其正式名稱為Transact-SQL,但一般程式設計師都稱其為T-SQL。 二、邏輯查詢處理各個階段 2.1 邏輯查詢處理流程總覽 2.2 邏輯查詢處理階段解釋   (1)FROM:標識出查詢的來源表,處理表

T-SQL查詢讀書筆記Part 2.執行計劃

一、關於執行計劃 執行計劃是優化器生成的用於確定如何處理一個給定查詢的“工作計劃”。一個計劃包含一組運算子,通常按照特定的順序來應用這些運算子。此外,一些運算子可以在它們之前的運算子還在處理時被應用(即不一定是完全序列),還有一些運算子也有可能被應用多次。 二、圖形化執行計劃 2.1 SSMS中

T-SQL查詢進階--理解SQL Server中索引的概念,原理以及其他

工具 def microsoft 需要 blog b- eve 實現 中一 簡介 在SQL Server中,索引是一種增強式的存在,這意味著,即使沒有索引,SQL Server仍然可以實現應有的功能。但索引可以在大多數情況下大大提升查詢性能,在OLAP

T-SQL查詢進階--深入淺出視圖

bsp images select語句 執行 lte 告訴 企業 contact 需要 簡介 視圖可以看作定義在SQL Server上的虛擬表.視圖正如其名字的含義一樣,是另一種查看數據的入口.常規視圖本身並不存儲實際的數據,而僅僅存儲一個Select語句和所

T-SQL 查詢分區詳細信息和行計數

function mes art dex sys prop sch pro left join --paritioned table and index detailsSELECT OBJECT_NAME(p.object_id) AS ObjectName,

tcp/ip 卷一 讀書筆記3)為什麽既要有IP地址又要有MAC地址

維護 移動 理論 集線器 協議 合並 所有 變更 影響 網絡層 首先明確一點,並不是所有的網絡之間傳輸數據都需要mac地址和ip地址,比如說點對點線路之間的通信就沒有MAC地址,網絡層使用ipx協議時就沒有ip地址,但是在當前的主流網絡中,我們都使用ip地址和mac地址 既

崔華基於oracle的SQL優化讀書筆記(一)如何得到真實的執行計劃

hash mes getting binary oracl only 中文 fun roc ---恢復內容開始--- 得到目標SQL的執行計劃,大致有以下四種方式: 1.explain plan 命令 2.DBMS_XPLAN包 3.SQLPLUS中的autotrace開關

T-SQL查詢語句

select t-sql 多表查詢 表達式 楊書凡 SQL語言中最主要、最核心的部分是它的查詢功能。查詢語句用來對已經存在於數據庫的數據按照特定的組合、條件表達式或次序進行檢索,使用SELECT語句來完成。使用SELECT查詢數據1. SELECT語法結構 T-SQL中查詢基

讀書筆記 2018-3-13

發的 相對 交流 工作 簡單 需要 自然 就是 傳統    Week 2 《構建之法》讀書筆記 關於敏捷開發的二三感想。 本周因課程原因,並未急於對書目進行大量的閱讀。而集中精讀了該書敏捷過程一章,先將該章主要內容和個人感悟總結如下。

T-SQL查詢:WITH AS 遞歸計算某部門的所有上級機構或下級機構

area t-sql union sel lec where 需要 _id with as drop table #Area; CREATE TABLE #Area ( id INT NOT NULL, city_name NVARCHAR(100)

T-SQL查詢進階--SQL Server中的事務與鎖

錯誤 span 設備 限制 數據復制 默認 base 數據 insert 為什麽需要鎖在任何多用戶的數據庫中,必須有一套用於數據修改的一致的規則,當兩個不同的進程試圖同時修改同一份數據時,數據庫管理系統(DBMS)負責解決它們之間潛在的沖突。任何關系數據庫必須支持事務的AC

SQL Server進階(一)T-SQL查詢和編程的背景

.com src 編程 server 分享 bubuko 進階 分享圖片 img SQL Server進階(一)T-SQL查詢和編程的背景

INSPIRED啟示錄 讀書筆記 - 第3章 產品管理與項目管理

red 啟示錄 隨著 特點 執行 緊迫感 積累 讀書 區別 兩者的關系 在傳統的零售軟件領域,產品經理常常兼任項目經理的工作,隨著互聯網的發展,兩者的職責區別也越來越明顯 產品管理的職責是探索(定義)有價值的、可用的、可行的產品 項目管理的職責是關註如何執行計劃以按期

多執行緒處理慢sql查詢筆記~

多執行緒處理慢sql查詢以及List(Array)的拆分 系統資料量不大,但是訪問速度特別慢,使用多執行緒優化一下!!! 優化結果:訪問時間縮短了十幾秒  25s --> 8s 一、List的拆分:Iterables.partition 注意: 引入的包為google名下的   &n

多線程處理慢sql查詢筆記~

拆分 集合 引入 form executor lists life 訪問速度 查詢 多線程處理慢sql查詢以及List(Array)的拆分 系統數據量不大,但是訪問速度特別慢,使用多線程優化一下!!! 優化結果:訪問時間縮短了十幾秒 25s --> 8s 一、Lis

Effective Java 第三版讀書筆記——條款3:使用私有構造器或列舉型別來強制實現 singleton 屬性

單例(singleton)就是一個只例項化一次的類。使類成為單例可能會使它的測試變得困難,因為除非它實現了作為其型別的介面,否則不可能用模擬實現來代替這個單例。下面是幾種實現單例的方法: 使用 public field 方法 // Singleton with public final field pub

程式碼整潔之道 讀書筆記 - 第3章 函式

短小 函式的第一規則是要短小。第二條規則是還要更短小。 函式20行封頂最佳。 if語句、else語句、while語句等,其中的程式碼塊應該只有一行,而且,塊內呼叫的函式擁有較具說明性的名稱,還能起到文件的作用。 只做一件事 函式應該做一件事。做好這件事。只做這一件事。 每個函式一個抽象層級 自頂

[SQL Server玩轉Python] 二.T-SQL查詢表格值及Python實現資料分析

在開發專案過程中,更多的是通過Python訪問SQL Server資料庫介面,進行資料探勘的操作;而SQL Server2016版本之後,嵌入了強大的R、Python、Machine Learning等功能,尤其是Python程式碼置於儲存過程中,可以實現一些便捷資料分析功能。 本系

Effective Java (3rd Editin) 讀書筆記3 類和介面

3 類和介面 Item 15:最小化類和成員的訪問許可權 一個設計優秀的類應該隱藏它的所有實現細節,將它的 API 和內部實現乾淨地分離開。這種軟體設計的基本準則被稱為“封裝”(encapsulation)。 封裝的優點: 組成系統的各元件之間解耦,使得它們能夠獨立地