1. 程式人生 > >程式設計師眼中的 SQL Server-非聚集索引能給我們帶來什麼?

程式設計師眼中的 SQL Server-非聚集索引能給我們帶來什麼?

寫在前面

最近在做的一個專案,頁面訪問的時候很慢(大概幾秒鐘的樣子),然後用日誌記錄的方式,來排查這個問題,最後發現是 Entity Framework 初始化的一個坑(大概要花 6-7 秒),詳見:《來,給Entity Framework熱熱身》,但是除了這個問題,還發現當一些使用者資料量很大的時候,訪問也是有些慢,這個就不是 Entity Framework 的問題了(因為初始化已完成),用 Sql Server Profiler 來跟蹤頁面訪問的時 SQL 的執行情況,因為應用程式很簡單,頁面載入的時候,跟蹤檢測到三個 SQL 執行,看了下也沒什麼問題(兩個獲取數量,一個獲取列表),數量獲取的 SQL,這個應該執行會很快,所以把分析焦點放在了那個獲取列表的 SQL 上,因為 SQL 沒什麼問題,那應該是關於這條 SQL 建的索引有問題。注:上面所說專案中大概有 100 萬的資料。

關於資料庫中的索引概念,記得在很早之前整理了一篇博文《T-Sql(八)欄位索引和資料加密》,現在來看,寫的真是一坨屎,概念講的再多沒個毛用,關鍵在於對實際應用中產生問題的分析。在研究這個問題之前,搜了一些相關資料,主要來自園中的幾位 SQL Server 大神(CareySon、樺仔、聽風吹雨等),稍微看了下,關於索引,主要是一些資料庫專業術語,看的不是很明白,作為程式設計師,我們知道索引分為聚集性索引和非聚集性索引,聚集性索引一般為主鍵(也可以不是),在建立表的時候會自動建立,針對上面我那個應用查詢問題,查詢條件是一些非主鍵欄位,所以這邊探討下非聚集性索引。

我不會說一些資料庫概念,所以只能用做一些實踐來理解概念的意義,以下應用場景中的用例是虛擬出來的,只是作為個人研究使用。

程式設計師應該有刨根問底的怪癖,雖然這是個資料庫問題。

應用場景

有一個 Product 表,欄位如下:

資料新增指令碼:

begin tran
    declare @index int
    set @index=0
    while(@index<1000000)
        begin
            insert into [dbo].[Product]([Name],Remarks,ProviderID,[Time],[State]) 
            values('我是測試標題1','我是測試備註1我是測試備註1我是測試備註1我是測試備註1我是測試備註1我是測試備註1',1,GETDATE(),0)
            insert into [dbo].[Product]([Name],Remarks,ProviderID,[Time],[State]) 
            values('我是測試標題2','我是測試備註2我是測試備註2我是測試備註2我是測試備註2我是測試備註2我是測試備註2',1,GETDATE(),1)
            insert into [dbo].[Product]([Name],Remarks,ProviderID,[Time],[State]) 
            values('我是測試標題3','我是測試備註3',3,GETDATE(),1)
            insert into [dbo].[Product]([Name],Remarks,ProviderID,[Time],[State]) 
            values('我是測試標題4','我是測試備註4我是測試備註4我是測試備註4我是測試備註4我是測試備註4我是測試備註4',4,GETDATE(),1)
            set @
[email protected]
+1 end commit

Product 表中插入了四百萬的資料,為了接近我們現實生產環境,所以對資料進行了不同插入。

一般應用環境查詢,有時候我們會針對一個欄位進行 where 查詢,有時候也會 and 另一個欄位進行查詢,這個時候,關於這兩個欄位的索引怎麼建?還是不需要建?是分別建兩個?還是建一個組合的?其實說真的,可能看到這的資料庫大神會莞爾一笑,但是作為程式設計師,這些我真不知道,搜尋的資料中也並沒有對這些雞毛蒜皮進行的說明,沒辦法,只能自己瞎折騰下。我們下面要做是 ProviderID 和 State 的查詢操作,有分別查詢,也有組合查詢,然後我們再對 Product 表建立這兩個欄位的索引,看看有什麼不同之處?還有就是針對不同的索引方式,查詢又會有什麼不同?我們睜大眼睛來看一下。

問題分析

我再對上面的分析進行說明下,首先,查詢主要為2種:

  1. where ProviderID=?
  2. where ProviderID=? and State=?

非聚集性索引的建立主要為3種:

  1. 不建立索引
  2. ProviderID 欄位索引
  3. ProviderID 和 State 欄位索引

針對這個應用場景和上面的分析,會得出 3*2 六種結果,其實我最想知道的是下面的第三種,即建立一個組合欄位索引,對單個欄位的查詢會不會有影響?還有就是反過來,單個欄位的索引建立,對組合欄位查詢會不會有影響?當然試過了才知道,看一下執行結果。

執行結果

測試指令碼:

declare @begin_date datetime
declare @end_date datetime
select @begin_date = getdate()
select * from [dbo].[Product] where ...
select @end_date = getdate()
select datediff(ms,@begin_date,@end_date) as '用時/毫秒'

為了接近測試結果,每次語句執行三次,然後再取平均值,截圖太麻煩了,這邊就直接貼下執行結果。

不建立索引

  1. where ProviderID=1(二百萬資料)
    執行結果:13806毫秒,13380毫秒,12730毫秒
    平均結果:13305毫秒

  2. where ProviderID=1 and State=1(一百萬資料)
    執行結果:6556毫秒,6613毫秒,6706毫秒
    平均結果:6625毫秒

建立索引欄位 ProviderID

  1. where ProviderID=1
    執行結果:13986毫秒,13810毫秒,15853毫秒
    平均結果:14549毫秒

  2. where ProviderID=1 and State=1
    執行結果:7153毫秒,7190毫秒,13950毫秒
    平均結果:7122毫秒

建立索引欄位 ProviderID 和 State

  1. where ProviderID=1
    執行結果:13840毫秒,14163毫秒,15853毫秒
    平均結果:14618毫秒

  2. where ProviderID=1 and State=1
    執行結果:7033毫秒,7220毫秒,7023毫秒
    平均結果:7152毫秒

結果分析

雖然測試的有些不完整,但是看到結果,哥有些凌亂了(建了索引,效能反而會降低?),難道是我插入的資料有問題?還是建立索引有問題?還是我人品有問題???坐等資料庫大神指教。。。

相關推薦

程式設計師眼中SQL Server聚集索引我們帶來什麼?

寫在前面 最近在做的一個專案,頁面訪問的時候很慢(大概幾秒鐘的樣子),然後用日誌記錄的方式,來排查這個問題,最後發現是 Entity Framework 初始化的一個坑(大概要花 6-7 秒),詳見:《來,給Entity Framework熱熱身》,但是除了這個問題,還發現當一些使用者資料量很大的時候,訪問也

程式設計師修煉之路(八)再次寫我們這些浮躁的程式設計師

本篇文章是程式設計師修煉之路的第八篇。 程式設計師修煉之路系列我決定將他定位於提升程式設計師素養的專欄,我會分享更多好的文章。 感謝原作者,因為你讓我思考 原文出處:http://blog.csdn.net/yzsind/article/details/6168854

Java程式記憶體分析:jdk自帶的jmap我們帶來什麼

jmap 打印出某個java程序(使用pid)記憶體內的,所有‘物件’的情況(如:產生那些物件,及其數量)。 可以輸出所有記憶體中物件的工具,甚至可以將VM 中的heap,以二進位制輸出成文字。使用方法 jmap -histo pid。如果連用SHELL jmap -histo pid&g

瞭解Sql Server的執行計劃 看懂SqlServer查詢計劃 程式設計師眼中SQL Server執行計劃教會我如何建立索引

閱讀目錄 如何啟動執行計劃 執行計劃結果要看什麼 Sql Server的五種查詢方式 檢視更具體的執行過程 參考資料   前一篇總結了Sql Server Profiler,它主要用來監控資料庫,並跟蹤生成的sql語句。但是隻拿到生成的sql語句沒有什麼用

程式設計師眼中SQL Server執行計劃教會我如何建立索引

先說點廢話 以前有 DBA 在身邊的時候,從來不曾考慮過資料庫效能的問題,但是,當一個應用程式從頭到腳都由自己完成,而且資料庫面對的是接近百萬的資料,看著一個頁面載入速度像烏龜一樣,自己心裡真是有種挫敗感。程式碼的優化問題,這是屬於程式設計師的職責範圍之內,對於我來說,這一方面比較好探查些,因為都是自己熟悉的

SQL Server 聚集索引的覆蓋,連接,交叉和過濾 <第二篇>

相對 col 超過 引用 保持 書簽 基本 nbsp 當我   在SQL Server中,非聚集索引其實可以看做是一個含有聚集索引的表,但相對實際的表來說,非聚集索引中所存儲的表的列數要少得多,一般就是索引列,聚集鍵(或RID)。非聚集索引僅僅包含源表中的非聚集索引的列和指

深入聚集索引:樓梯SQL Server二級索引

statistic line nts find res rod -c pac 發布 通過大衛·杜蘭特,2017/10/18(第一次出版:2014/11/26) 該系列 本文是樓梯系列的一部分:SQL Server的階梯索引 索引數據庫設計的基礎,告訴開發人員使用數據庫設計

SQL SERVER 聚集索引 聚集索引 區別

poi 字典 問題 statistic 速度 左右 dbcc 表示 diff 轉自http://blog.csdn.net/single_wolf_wolf/article/details/52915862 一、理解索引的結構   索引在數據庫中的作用類似於目錄在書籍中的作

SQL Server 聚集索引的覆蓋,連線,交叉和過濾 (第二篇)

在SQL Server中,非聚集索引其實可以看做是一個含有聚集索引的表,但相對實際的表來說,非聚集索引中所儲存的表的列數要少得多,一般就是索引列,聚集鍵(或RID)。非聚集索引僅僅包含源表中的非聚集索引的列和指向實際物理表的指標。 一、非聚集索引之INCLUDE   非聚集索引其實可以看做一

淺談sql server聚集索引聚集索引

今天同事的服務程式在執行批量插入資料操作時,會超時失敗,程式碼debug了幾遍一點問題都沒有,SQL單條插入也可以正常錄入資料,除錯了一上午還是很迷茫,場面一度很尷尬,最後還是發現了問題的根本,原來是另一個同事為了提升查詢效率濫用了索引在搞鬼,沒有合理的運用索引使每次新增和修改資料時效率極低,大批量插入和修改

SQL Server 深入解析索引儲存(聚集索引)

概述   非聚集索引與聚集索引具有相同的 B 樹結構,它們之間的顯著差別在於以下兩點: 基礎表的資料行不按非聚集鍵的順序排序和儲存。 非聚集索引的葉層是由索引頁而不是由資料頁組成。

SQL Server 索引和表體系結構(聚集索引

非聚集索引 概述      對於非聚集索引,涉及的資訊要比聚集索引更多一些,由於整個篇幅比較大涉及接下來的要寫的“包含列的索引”,“索引碎片”等一些知識點,可能要結合起來閱讀理解起來要更容易一些。非聚集索引和聚集索引一樣都是B-樹結構,但是非聚集索引不改變資料的儲存方式,所以一個表允許建多個非聚集索引;非

Sql Server之旅---你必須知道的聚集索引掃描

      非聚集索引,這個是大家都非常熟悉的一個東西,有時候我們由於業務原因,sql寫的非常複雜,需要join很多張表,然後就淚流滿面了。這時候就有DBA或者資深的開發給你看這個猥瑣的sql,通過執行計劃一分析,或許就看出了不該有的表掃描,萬惡之源。然後給你在關鍵的欄位加

SQL SERVER大話儲存結構(2)_聚集索引如何查詢到行記錄

1 行記錄如何儲存     這裡引入兩個概念:堆跟聚集索引表。本部分參考MSDN。 1.1 堆表     堆表,沒有聚集索引的表格,可以建立一個或者多個非聚集索引。沒有按照某個規則進行儲存,一般來說,按照行記錄入表的順序,但是由於效能要求,可能會在不同區域移動入庫資料

SQL Server聚集索引聚集索引

轉載:http://www.cnblogs.com/tuyile006/archive/2009/08/28/1555615.html 微軟的SQL SERVER提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclust

SQL有三個類型的索引,唯一索引有重復,但聚集索引聚集索引可以有重復

返回 自動添加 post 設置 span 唯一索引 tca lock 所有 重要: (1) SQL如果創建時候,不指定類型那麽默認是非聚集索引 (2) 聚集索引和非聚集索引都可以有重復記錄,唯一索引不能有重復記錄。 (3) 主鍵 默認是加了唯一約束的聚集索引,但是也可

程式設計師眼中的瀏覽器是什麼樣的?IE:有本事你卸了我啊

瀏覽器之爭從上個世紀就已經開始,已經持續了很長的時間。到目前為止,競爭依然激烈。在很多年前,IE還是最主流的web瀏覽器。但現在形勢早已完全不同了,不知道大家還有多少人在用IE瀏覽器?今天,小編向大家分享一下針對IE的搞笑圖片,只是逗樂而已,希望大家看的開心! 1、當瀏覽器化作一種槍,你喜歡用哪

程式設計師眼中的瀏覽器是什麼樣的?IE:有本事你就把我卸了啊

瀏覽器之爭從上個世紀就已經開始,已經持續了很長的時間。到目前為止,競爭依然激烈。在很多年前,IE還是最主流的web瀏覽器。但現在形勢早已完全不同了,不知道大家還有多少人在用IE瀏覽器?今天,小編向大家分享一下針對IE的搞笑圖片,只是逗樂而已,希望大家看的開心! 1、當瀏覽器化作一種槍,你喜歡用哪

程式設計師眼中的能者多勞,是「坑」麼?

點選上方“程式人生”,選擇“置頂公眾號” 第一時間關注程式猿(媛)身邊的故事 作者 上海小胖 原文標題 能者多勞,等待上帝的眷顧,若是個坑,我寧願跳進去再爬上來 如需轉載,請聯絡我們。 目錄: 1. 只有“能者”才能多勞 2. “能者”喜

[轉]國外程式設計師推薦:每個程式設計師都應該讀的程式設計書

五年前有網友在 Stackoverflow 發帖提問:『程式設計師應該讀哪些非程式設計方面的書?』。有很多程式設計師響應,他們在推薦的同時也寫下了自己的評語。本文摘編其中 29 本書,下面就按照各書的推薦數排列。另外,本月初我們在伯樂頭條也發起了相同的討論帖《你最喜歡的非程式設計書是哪一本?》,已有很多的朋友