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

来源: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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...