對聚集表查詢的時候,未顯式指定排序列的時候,預設查詢結果的順序一定是按照聚集索引順序排序的嗎

来源:http://www.cnblogs.com/wy123/archive/2016/04/23/5425946.html
-Advertisement-
Play Games

在sql server 中,如果一張表存在聚集索引的時候,大多數情況下,如果進行select * from TableName查詢,預設的返回順序是按照聚集所在列的順序返回的 但是,在一張表存在聚集索引的時候,並不一定所有的情況都是按照聚集索引列的順序排列的, 下麵開始測試 如下查詢完全沒有問題,正 ...


在sql server 中,如果一張表存在聚集索引的時候,大多數情況下,如果進行select * from TableName查詢,預設的返回順序是按照聚集所在列的順序返回的

但是,在一張表存在聚集索引的時候,並不一定所有的情況都是按照聚集索引列的順序排列的,

下麵開始測試

 

create table TestDefaultOrder
(
	Id int identity(1,1) primary key,--主鍵上預設會建立聚集索引
	Col2 char(5),
	COL3 char(5)
)
--寫入100000條測試數據
insert into TestDefaultOrder  values (SUBSTRING(cast(NEWID() as varchar(50)),1,5),SUBSTRING(cast(NEWID() as varchar(50)),1,5))
go 100000

如下查詢完全沒有問題,正如你所預料的,按照聚集索引所在的列(Id)排序的,完全沒有問題,下麵開始切入正題

 

--創建一張同樣的對照表
create table TestDefaultOrder_Contrast
(
	Id int identity(1,1) primary key,--主鍵上預設會建立聚集索引
	Col2 char(5),
	COL3 char(5)
)

--將TestDefaultOrder表中的數據寫入進去,目前,兩張表的數據和索引結構一模一樣
insert into TestDefaultOrder_Contrast (Col2,Col3)  
select Col2,Col3 from TestDefaultOrder

--僅僅在對照表上創建一個非聚集索引,這是唯一的不同點
Create Index idx2 on TestDefaultOrder_Contrast(Col2,Col3)

接下來的查詢,或許會有一點一點出乎你的意料,

上面說了,兩張表的數據是一模一樣的,聚集索引結構也是一樣的,只是對照表多個一個非聚集索引

發現對照表的結果返回順序,根本是按照聚集索引的排序返回的

 

那麼原因在哪裡呢?我們要從不同類似索引占用的空間情況進行分析,通過dm_db_index_physical_stats發現,在數據數據完全一致的情況下,

因為TestDefaultOrder_Contrast這個表上的非聚集索引,占用的空間更少(248個page,而TestDefaultOrder的聚集索引是285個page),

正因為此,sqlserver在進行全表掃描的時候,會選擇一個代價更小的索引(進行掃描),

因為TestDefaultOrder表上只有一個聚集索引,按照聚集索引掃描進行查詢,返回的結果的順序是按照聚集索引列排序的

但是TestDefaultOrder_Contrast就不同了,因為在非聚集索引idx2 上,包含了全部的數據(Col2,Col3以及指向聚集索引鍵值的Id),

但idx2這個索引是占用的空間更小,所以對於TestDefaultOrder_Contrast的查詢,是按照idx2這個非聚集索引進行掃描的

 

 

 

 

因為,在TestDefaultOrder_Contrast這個表上,

直接select * TestDefaultOrder_Contrast進行查詢的話,

跟對錶TestDefaultOrder進行 select * TestDefaultOrder查詢

是用兩種完全不同的方式進行的,出來的結果自然也就不同了

 

 

而事實上,sqlserver在對TestDefaultOrder_Contrast進行查詢的時候,通過走idx2這個索引掃描,代價確實要比TestDefaultOrder的聚集索引掃描,代價要小

 

如果有興趣的話,再次分析為什麼存儲同樣的數據(TestDefaultOrder上的聚集索引和TestDefaultOrder_Contrast的非聚集索引idx2),

TestDefaultOrder表上的聚集索引,要比TestDefaultOrder_Contrast上的idx2(Create Index idx2 on TestDefaultOrder_Contrast(Col2,Col3))占用的空間大呢

這裡的原因在於,一個表上的聚集索引(於非聚集索引相比),除了要存儲數據,要維護的信息更多的元數據信息,占用的空間自然就較多一點

而sqlserver在進行查詢的時候,總是會選擇一個代價相對較低的方式。

 

總結:千萬不要以為,只要表上建立了聚集索引,在查詢的時候,返回結果的預設的排序方式,是按照聚集索引來的

 

 

 

後記:為什麼要研究這個問題?

因為之前遇到過,某些查詢沒有顯式指定排序列,但是藉助表上聚集索引,返回結果的時候,會得一個想要的順序。

這種情況其實會潛在一種問題,如果發生類似上面這種情況,想要對查詢結果按照聚集索引的順序排序,而又不顯式制定排序列,查詢結果的顯示順序,可就不一定了。

 


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

-Advertisement-
Play Games
更多相關文章
  • 1,socket是什麼? 2,socket的作用 3,socket怎麼用 4,socket的擴展 —————————————————————— socket是什麼? Socket這個名詞現在有很多不同的意思,這裡主要講到其中2個含義。一是,套接字socket=(IP地址:埠號),是端的概念。二是, ...
  • 下載地址:https://github.com/romaonthego/RESideMenu 效果如下:官方案例 自己的實現效果 具體代碼下: AppDelegate.m文件中 - (BOOL)application:(UIApplication *)application didFinishLau ...
  • 正則表達式完成號碼驗證, ^以某開頭,[] 字元集(匹配中括弧裡面的任意字元),\d是任意一個數字,{n}表示出現了多少次,$結尾 手機號的正則 ^1[34568]\d{9}$,以1開頭,第二個數字是34568,剩下九個都是數字,數字結尾 調用String對象的match()方法,參數:正則(裡面的 ...
  • 1.在使用代碼中使用通知進行值的傳遞的時候,開闢了一個通知,最後記得移除這個通知,那樣的話這個通知一直存在,假如再運行相同的代碼的時候就會註冊2個通知中心,分別執行對應的事件方法,從而造成了資源的浪費。 (1)這時我發現在二級子控制項中有個有一個UINavigationButton,就是要更改的取消按 ...
  • 通知/代理/block都可以傳值(順傳倒傳都可以)一 順傳 用屬性傳值最簡單明瞭二 逆傳 用block更簡潔三 通知傳值使用場景 1- 很多控制器都需要知道一個事件,應該用通知(傳遞參數的過程就是傳值); 2 - 相隔多層的兩個控制器之間傳值————————————————————————————— ...
  • 1.伺服器會給一個證書,一般為.pem格式證書 2.將.pem格式的證書轉換成.cer格式的證書 打開電腦自帶終端 ,進入到桌面 cd Desktop 回車回到桌面Desktop Admin$ 輸入命令 openssl x509 -in 你的證書.crt -out 你的證書.cer -outform ...
  • 本文主要從 Android版本與對應的linux內核版本關係 和 Android系統架構 兩部分來討論。 1、Android版本與Linux內核的關係 (1)Android最初使用Linux2.6作為其內核,隨著Android與Linux內核的發展,不同版本的Android使用的linux內核版本差 ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...