SQL Server 2012 ColumnStore索引测试

简介:
复制代码
主要是和普通的索引进行对比:

/********************
准备数据
*****************
*/
select * into ColumnStoreTest from northwind..orders

declare @i int
set @i = 12
while(@i > 0)
begin
insert into ColumnStoreTest
select * from ColumnStoreTest
union all
select * from ColumnStoreTest
set @i = @i-1
end

--顺带提一下,因为 into 会把 identity 也写进去,为了方便 我就把ColumnStoreTest 的 identity 给散掉了
复制代码

@i 用12 可能数据量有点多,可以自己调整

复制代码
/**************************
创建columnstrore index
***********************
*/

create index idx_CustomerID on ColumnStoreTest(CustomerID,Freight)


create columnstore index csidx_CustomerID on ColumnStoreTest(CustomerID,Freight)
复制代码

 

复制代码
这个是使用第一个索引测试产生的结果

  SQL Server 分析和编译时间: 
  CPU 时间 = 0 毫秒,占用时间 = 5 毫秒。

(89 行受影响)
'ColumnStoreTest'。扫描计数 5,逻辑读取 7352 次,物理读取 0 次,预读 32 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(6 行受影响)

(1 行受影响)

SQL Server 执行时间:
CPU 时间 = 1529 毫秒,占用时间 = 544 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

执行计划也没什么特别的就是 普通的索引扫描
select CustomerID,sum(Freight) from ColumnStoreTest group by CustomerID
|--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [globalagg1006]=(0) THEN NULL ELSE [globalagg1008] END))
|--Stream Aggregate(GROUP BY:([Northwind].[dbo].[ColumnStoreTest].[CustomerID]) DEFINE:([globalagg1006]=SUM([partialagg1005]), [globalagg1008]=SUM([partialagg1007])))
|--Parallelism(Gather Streams, ORDER BY:([Northwind].[dbo].[ColumnStoreTest].[CustomerID] ASC))
|--Stream Aggregate(GROUP BY:([Northwind].[dbo].[ColumnStoreTest].[CustomerID]) DEFINE:([partialagg1005]=COUNT_BIG([Northwind].[dbo].[ColumnStoreTest].[Freight]), [partialagg1007]=SUM([Northwind].[dbo].[ColumnStoreTest].[Freight])))
|--Index Scan(OBJECT:([Northwind].[dbo].[ColumnStoreTest].[idx_CustomerID]), ORDERED FORWARD)
复制代码

 

复制代码
SQL Server 分析和编译时间: 
CPU 时间 = 16 毫秒,占用时间 = 93 毫秒。

(89 行受影响)
'ColumnStoreTest'。扫描计数 4,逻辑读取 34 次,物理读取 2 次,预读 18 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(7 行受影响)

(1 行受影响)

SQL Server 执行时间:
CPU 时间 = 63 毫秒,占用时间 = 281 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

select CustomerID,sum(Freight) from ColumnStoreTest group by CustomerID
|--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [globalagg1006]=(0) THEN NULL ELSE [globalagg1008] END))
|--Stream Aggregate(GROUP BY:([Northwind].[dbo].[ColumnStoreTest].[CustomerID]) DEFINE:([globalagg1006]=SUM([partialagg1005]), [globalagg1008]=SUM([partialagg1007])))
|--Sort(ORDER BY:([Northwind].[dbo].[ColumnStoreTest].[CustomerID] ASC))
|--Parallelism(Gather Streams)
|--Hash Match(Partial Aggregate, HASH:([Northwind].[dbo].[ColumnStoreTest].[CustomerID]), RESIDUAL:([Northwind].[dbo].[ColumnStoreTest].[CustomerID] = [Northwind].[dbo].[ColumnStoreTest].[CustomerID]) DEFINE:([partialagg1005]=COUNT_BIG([Northwind].[dbo].[ColumnStoreTest].[Freight]), [partialagg1007]=SUM([Northwind].[dbo].[ColumnStoreTest].[Freight])))
|--Index Scan(OBJECT:([Northwind].[dbo].[ColumnStoreTest].[csidx_CustomerID]))
复制代码

可以从这2个结果中看出,逻辑读的数量columnstore index 明显比 普通索引的少,这也就是 columnstore 索引的优势

但是如果是普通的select * from where 这类语句那columnstore index 还有优势嘛?

是不是和 oracle的bitmapindex 一样在 or 语句中 也很有优势呢?

在columnstore index 状况下的执行计划没有一点优势:
因为大家对非聚集索引比较了解,我也就不发非聚集索引在这种状况下的执行计划了。
select * from ColumnStoreTest where customerid = 'VINET' or customerid = 'TOMSP'
|--Parallelism(Gather Streams)
|--Table Scan(OBJECT:([Northwind].[dbo].[ColumnStoreTest]), WHERE:([Northwind].[dbo].[ColumnStoreTest].[CustomerID]=N'TOMSP' OR [Northwind].[dbo].[ColumnStoreTest].[CustomerID]=N'VINET'))
都已经是表扫描了其实也没什么好说的了。

上面的例子是再选择性低的情况下的执行计划。

那么如果选择性高又会怎么样呢?

复制代码
SQL Server 分析和编译时间: 
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 16 毫秒,占用时间 = 28 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

(1 行受影响)
'ColumnStoreTest'。扫描计数 1,逻辑读取 12 次,物理读取 0 次,预读 2 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(4 行受影响)

(1 行受影响)

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 86 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SELECT * FROM [ColumnStoreTest] WHERE [orderid]=@1
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
|--Index Scan(OBJECT:([Northwind].[dbo].[ColumnStoreTest].[csidx_orderID]), WHERE:([Northwind].[dbo].[ColumnStoreTest].[OrderID]=(10248)))
|--RID Lookup(OBJECT:([Northwind].[dbo].[ColumnStoreTest]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)

SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 9 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

(1 行受影响)
'ColumnStoreTest'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(4 行受影响)

(1 行受影响)

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 92 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SELECT * FROM [ColumnStoreTest] WHERE [orderid]=@1
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
|--Index Seek(OBJECT:([Northwind].[dbo].[ColumnStoreTest].[idx_orderid]), SEEK:([Northwind].[dbo].[ColumnStoreTest].[OrderID]=(10248)) ORDERED FORWARD)
|--RID Lookup(OBJECT:([Northwind].[dbo].[ColumnStoreTest]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
csidx_orderid 是columnstore index
idx_orderid 是非聚集索引
仔细比较逻辑读,就能看出,在高选择性,传统索引是比较又优势的。
复制代码

关于or,理论上来说是columnstore index 比非聚集索引又优势。

因为我相信,columnstore index 是和bitmap index 相同原理的。

如果对bitmap index 不太了解可以参考:《expert oracle database architecture》中的相关章节





    本文转自 Fanr_Zh 博客园博客,原文链接:http://www.cnblogs.com/Amaranthus/archive/2011/11/28/2266165.html,如需转载请自行联系原作者




相关文章
|
3月前
|
人工智能 自然语言处理 JavaScript
利用MCP Server革新软件测试:更智能、更高效的自动化
MCP Server革新软件测试:通过标准化协议让AI实时感知页面结构,实现自然语言驱动、自适应维护的自动化测试,大幅提升效率,降低脚本开发与维护成本,推动测试左移与持续测试落地。
|
6月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
9月前
|
SQL 存储 关系型数据库
SQL优化策略与实践:组合索引与最左前缀原则详解
本文介绍了SQL优化的多种方式,包括优化查询语句(避免使用SELECT *、减少数据处理量)、使用索引(创建合适索引类型)、查询缓存、优化表结构、使用存储过程和触发器、批量处理以及分析和监控数据库性能。同时,文章详细讲解了组合索引的概念及其最左前缀原则,即MySQL从索引的最左列开始匹配条件,若跳过最左列,则索引失效。通过示例代码,展示了如何在实际场景中应用这些优化策略,以提高数据库查询效率和系统响应速度。
395 10
|
4月前
|
JSON Java Shell
多线程的 udp client server 测试demo
本示例展示了使用 Python 实现的 UDP 客户端与服务端通信,支持多线程、线程池、JSON 格式传输、UUID 生成、超时设置及 search_id 校验功能,适用于高并发场景下的数据交互需求。
多线程的 udp client server 测试demo
|
10月前
|
SQL 索引
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
|
7月前
|
测试技术 Go 开发者
如何为 gRPC Server 编写本地测试代码
本文介绍了如何使用 Go 语言中的 gRPC 测试工具 **bufconn**,通过内存连接实现 gRPC Server 的本地测试,避免端口冲突和外部依赖。结合示例代码,讲解了初始化内存监听、自定义拨号器及编写测试用例的完整流程,并借助断言库提升测试可读性与准确性。适用于单元及集成测试,助力高效开发。
164 1
|
11月前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
398 2
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
257 3
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引:详细技巧与方法
在数据库管理中,索引是提高SQL查询性能的重要手段
2488 5
|
SQL 存储 关系型数据库
SQL默认索引是什么:深入解析与技巧
在SQL数据库中,索引是一种用于提高查询性能的重要数据结构