1. 程式人生 > >通過非聚集索引讓select count(*) from 的查詢速度提高几十倍、甚至千倍

通過非聚集索引讓select count(*) from 的查詢速度提高几十倍、甚至千倍

通過非聚集索引,可以顯著提升count(*)查詢的效能。

有的人可能會說,這個count(*)能用上索引嗎,這個count(*)應該是通過表掃描來一個一個的統計,索引有用嗎?


不錯,一般的查詢,如果用索引查詢,也就是用Index Seek了,查詢就會很快。

 

之所以快,是由於查詢所需要訪問的資料只佔整個表的很小一部分,如果訪問的資料多了,那反而不如通過表掃描來的更快,因為掃描用的是順序IO,效率更高,比運用隨機IO訪問大量資料的效率高很多。

 

相應的,如果只需要訪問少量資料,那麼索引查詢的效率遠高於表掃描,因為通過隨機IO來訪問少量資料的效率遠高於通過順序IO來訪問少量資料,之所以掃描的效率較低是由於掃描訪問了很多不需要的資料。

 

那麼,通過非聚集索引,提升select count(*) from 的查詢速度的本質在於,非聚集索引所佔空間的大小往往,遠小於聚集索引或堆表所佔用的空間大小;

同樣的,表中佔用較少位元組的欄位的非聚集索引,對於速度的提升效果,也要遠大於,佔用較多位元組的欄位的非聚集索引,因為佔用位元組少,那麼索引佔用的空間也少,同樣是掃描,只需要更少的時間,對硬碟的訪問次數也更少,那麼速度就會更快了。


下面通過一個實驗,來說明非聚集索引為什麼能提高count(*)的查詢速度。


1、建表,插入資料

[sql]
  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. if OBJECT_ID('test'is not null  
  2.    drop table test  
  3. go  
  4.   
  5. create table test  
  6. (  
  7. id int
     identity(1,1),  
  8. vid int ,  
  9. varchar(600),  
  10. constraint pk_test_id primary key (id)  
  11. )  
  12. go  
  13.   
  14.   
  15.   
  16. insert into test(vid,v)  
  17. select 1,REPLICATE('a',600) union all  
  18. select 2,REPLICATE('b',600) union all  
  19. select 3,REPLICATE('c',600) union all  
  20. select 4,REPLICATE('d',600) union all  
  21. select 5,REPLICATE('e',600) union all  
  22. select 6,REPLICATE('f',600) union all  
  23. select 7,REPLICATE('g',600) union all  
  24. select 8,REPLICATE('h',600) union all  
  25. select 9,REPLICATE('i',600) union all  
  26. select 10,REPLICATE('j',600)  
  27. go  
  28.   
  29.   
  30. --select POWER(2,18) * 10  
  31. --2621440條資料  
  32. begin tran  
  33.     insert into test(vid,v)  
  34.     select vid,v  
  35.     from test  
  36. commit  
  37. go 18  
  38.   
  39.   
  40. --建立非聚集索引  
  41. create index idx_test_vid on test(vid)  


2、檢視採用聚集索引和非聚集索引後,查詢的資源消耗

[sql]  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. --輸出詳細的IO和時間(cpu、流逝的時間)上的開銷資訊  
  2. set statistics io on  
  3. set statistics time on  
  4.   
  5.   
  6. /* 採用聚集索引  
  7.   
  8. SQL Server 分析和編譯時間:   
  9.    CPU 時間 = 0 毫秒,佔用時間 = 0 毫秒。  
  10.   
  11. (1 行受影響)  
  12. 表 'test'。掃描計數 5,邏輯讀取 206147 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。  
  13.   
  14.  SQL Server 執行時間:  
  15.    CPU 時間 = 921 毫秒,佔用時間 = 277 毫秒。  
  16. */  
  17. select COUNT(*)  
  18. from test with(index (pk_test_id))  
  19.   
  20.   
  21.   
  22. /*採用非聚集索引  
  23.   
  24. SQL Server 分析和編譯時間:   
  25.    CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。  
  26.   
  27. (1 行受影響)  
  28. 表 'test'。掃描計數 5,邏輯讀取 4608 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。  
  29.   
  30.  SQL Server 執行時間:  
  31.    CPU 時間 = 327 毫秒,佔用時間 = 137 毫秒。  
  32. */  
  33. select count(*)  
  34. from test with(index (idx_test_vid))  


相關推薦

通過聚集索引select count(*) from查詢速度提高甚至

通過非聚集索引,可以顯著提升count(*)查詢的效能。 有的人可能會說,這個count(*)能用上索引嗎,這個count(*)應該是通過表掃描來一個一個的統計,索引有用嗎? 不錯,一般的查詢,如果用索引查詢,也就是用Index Seek了,查詢就會很快。  

通過聚集索引select count(*) from查詢速度提高甚至

意思 topic sni article 分析 簡單 主鍵 begin 應該 通過非聚集索引,可以顯著提升count(*)查詢的性能。 有的人可能會說,這個count(*)能用上索引嗎,這個count(*)應該是通過表掃描來一個一個的統計,索引有用嗎? 不錯,一般

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的階梯索引 索引數據庫設計的基礎,告訴開發人員使用數據庫設計

數據庫存儲結構:頁聚集索引聚集索引

創建 方法 6.2 insert語句 方式 放置 變化 分支 通過 數據庫存儲結構:頁、聚集索引、非聚集索引 想了解數據庫存儲結構,因先了解數據庫的訪問方式然後從原理上理解數據庫存儲結構方式。 一、SQL Server中訪問數據的方式 從廣義上講,SQL Server檢索所

學習筆記(九)——數據庫存儲結構:頁聚集索引聚集索引

分享 style end 宋體 blog lec storage rop cas 1、頁 SQL Server用8KB 的頁來存儲數據,並且在SQL Server裏磁盤 I/O 操作在頁級執行。也就是說,SQL Server 讀取或寫入所有數據頁。頁有不同的類型,像

聚集索引聚集索引

每次 方式 possible .com 表數據 alt ons row span 一.非聚集索引(MyISAM的索引方式): 使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址.主鍵索引圖: 輔助索引圖: 主鍵索引和輔助索引沒有本質上的區別,da

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

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

搜索引擎算法研究專題三:聚集索引聚集索引介紹

運算符 sof 節點 信息 ont ros 頁碼 存儲 定位 搜索引擎算法研究專題三:聚集索引與非聚集索引介紹 聚集索引介紹   在聚集索引中,表中各行的物理順序與鍵值的邏輯(索引)順序相同。表只能包含一個聚集索引。   如果不是聚集索引,表中各行的物理順序與鍵值的邏

MySQL聚集索引聚集索引

高效 mar lock 包含 排列 查找 存儲 clust gin 索引分為聚集索引和非聚集索引,mysql中不同的存儲引擎對索引的底層實現可能會不同,這裏只關註mysql的默認存儲引擎InnoDB。 利用下面的命令可以查看默認的存儲引擎 show variables li

數據庫索引(二)聚集/聚集索引索引和鎖

mysql聚集索引(InnoDB,使用B+Tree作為索引結構)在一個結構中保存了b-tree索引和數據行;按照主鍵的順序存儲在葉子頁上;主鍵索引:葉節點存儲(主鍵數據:所有剩余列數據)二級索引(非聚簇索引):葉節點存儲(索引列數據:主鍵數據)非葉節點只存儲 索引列優點:可以把相關數據保存在一起,如根據用戶i

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

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

聚集索引聚集索引

details size font itl spa net blank http href https://blog.csdn.net/zc474235918/article/details/50580639 https://blog.csdn.net/jiadajing2

聚集索引聚集索引

圖片 數據塊 找到 tro pan 使用 所有 多個 lib 聚集(clustered)索引   數據行的的物理順序與列值(一般主鍵事務那一列)的邏輯順序相同,一個表中只能有一個聚集索引。   一個表就像以前用的新華字典,聚集索引就像拼音目錄,而每個字存放的頁碼就是數據的物

select count(*) from user註入

select from pre rom col 直接 語句 bstr lec 先來看一條sql語句: 1 mysql> select * from flag where id =1; 2 +------+----------+----------+---------

聚集索引聚集索引及在sqlite使用。

dci 時間 strong ger androi 不等式 cluster ble 類型 聚集索引一個表只能有一個,而非聚集索引一個表可以存在多個。 聚集索引存儲記錄是物理上連續存在,而非聚集索引是邏輯上的連續,物理存儲並不連續。 create clustered index

Innodb,MyIsam,聚集索引聚集索引

Innodb和Myisam是什麼和區別 Innodb和Myisam是兩種類型別,在navicat中可以看到,也可以修改。 下面介紹一下他們的區別: 區別 Innodb Myisam

BTREE索引和HASH索引聚集索引聚集索引

https://www.jianshu.com/p/76530afa13cb https://blog.csdn.net/yifanSJ/article/details/79220044 BTREE索引和HASH索引 1、不同引擎的預設索引 不同的引擎對於索引有不同的支援:Innod

使用JDBC獲取select count(*) from table_name

public int getCount() { int count = 0; PreparedStatement ps = null;         ResultSet rs = null;   &

RestHighLevelClient 實現 select count from table group by filed

String id = null; try {SearchRequest request = new SearchRequest(IndexAndTypeConstant.PROPERTY_SQL); request.types(IndexAndTypeConst