内存中OLTP(Hekaton)的排序警告
内存中OLTP是关于内存中的一切。但那只是对了一半。在今天的文章里我想给你展示下,当你从内存读取数据时,即使内存中OLTP也会引起磁盘活动。这里的问题是执行计划里,不正确的统计信息与排序(sort)运算符的组合。
排序(sort)运算符问题
我们都知道,排序(sort)运算符需要所谓的内存授予(Memory Grant)来作它的运行。内存区域是用来进行执行计划里到来记录的排序。内存授予的大小是基于估计行数数量。在基数计算(Cadinality Estimation)期间查询优化器估计执行计划里每个运算符的预计行数。
我在今年6月写了篇文章,展示了当估计错误时,排序(sort)运算符如何能溢出到TempDb。在内存中OLTP里同样的事情会发生:当估计行数错误时,在执行计划里有排序(sort)运算符,排序(sort)运算符会溢出到TempDb!我们来重现这个情形。
内存中OLTP溢出到TempDb
我们新建一个有内存中OLTP文件组配置的新数据库。
-- Create new database
CREATE DATABASE HashCollisions
GO -- Add MEMORY_OPTIMIZED_DATA filegroup to the database.
ALTER DATABASE HashCollisions
ADD FILEGROUP InMemoryOLTPFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
GO USE HashCollisions
GO -- Add a new file to the previously created file group
ALTER DATABASE HashCollisions ADD FILE
(
NAME = N'InMemoryOLTPContainer',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.SQL2014\MSSQL\DATA\InMemoryOLTPContainer'
)
TO FILEGROUP [InMemoryOLTPFileGroup]
GO
下一步我创建新的内存优化表:
-- Create a test table
CREATE TABLE Table1
(
Column1 INT IDENTITY,
Column2 INT
CONSTRAINT pk_Column1 PRIMARY KEY NONCLUSTERED HASH (Column1) WITH (BUCKET_COUNT = 1)
) WITH
(
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_ONLY
)
GO
从表定义可以看到,我在Column1列创建了1个哈希索引。因为它是个哈希索引,你也需要指定哈希表上你想拥有的哈希桶数。这里我指定了1个哈希桶,这是个非常,非常糟的做法。当你往表里插入记录时,因为只有1个哈希桶,你会得到巨大数量的哈希冲突(hash collisions)。一般来说,在你定义你的哈希索引的列上,哈希桶数应该和你列上的唯一值个数一致。下面代码往刚才创建的表里插入14001条记录。
-- Insert 14001 records
INSERT INTO Table1(Column2) VALUES (1) SELECT TOP 14000 IDENTITY(INT, 1, 1) AS n INTO #Nums
FROM
master.dbo.syscolumns sc1 INSERT INTO Table1 (Column2)
SELECT 2 FROM #nums
DROP TABLE #nums
GO
你可以通过DMV sys.dm_db_xtp_hash_index_stats查看哈希冲突数。从这个DMV的输出可以看到,你有14001条记录在这个且唯一的哈希索引的哈希桶上。现在我们来运行执行计划里有排序(sort)运算符的SELECT语句。
-- The sort operator in this execution plan spills over to TempDb!
SELECT * FROM Table1
ORDER BY Column1
现在当你查看执行计划时,你会看到排序运算符已经溢出到TempDb。
这是因为哈希索引上不正确的统计信息才发生的。当你查看执行计划里Index Scan (NonClusteredHash) 运算符属性时,你会看到查询优化器从我们的哈希索引上估计行数为1,实际我们返回了140001行。
Index Scan (NonClusteredHash) 运算符的估计总是基于哈希表里哈希桶数。查询优化器这里做出的假设是你没有哈希冲突(hash collisions)——这在这里是不正确的。因此对排序运算符的内存授予是根据那个不正确的估计作为标准,这就会溢出到TempDb。在我的系统里这个查询运行了近80毫秒,对于内存中技术来说这个算很长时间了。
你如何修正这个问题?删除你的表,在哈希索引里仔细计划哈希桶数。欢迎来到内存中OLTP的精彩世界……
小结
当你使用内存中OLTP的哈希索引时,你要对你的哈希所用仔细设计你的哈希桶数。当它们错误时,是伤及性能。我已经在1个月前,写了篇文章描述哈希冲突(hash collisions)如何伤及内存中OLTP的性能——即使没有溢出到TempDb!
从中我们可以看出:在哈希索引有哈希冲突的话,你用内存中OLTP的话不能期望得到惊艳的快速性能,因为它们带来巨大的负担且影响基数计算。
感谢关注!
参考文章:
https://www.sqlpassion.at/archive/2015/02/05/memory-oltp-hekaton-sort-warnings/
内存中OLTP(Hekaton)的排序警告的更多相关文章
- 内存中OLTP(Hekaton)里的事务日志记录
在今天的文章里,我想详细讨论下内存中OLTP里的事务日志如何写入事务日志.我们都知道,对于你的内存优化表(Memory Optimized Tables),内存中OLTP提供你2个持久性(durabi ...
- SQL Server 内存中OLTP内部机制概述(一)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(三)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...
- SQL Server 内存中OLTP内部机制概述(三)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- 配置内存中OLTP文件组提高性能
在今天的文章里,我想谈下使用内存中OLTP的内存优化文件组来获得持久性,还有如何配置它来获得高性能.在进入正题前,我想简单介绍下使用你数据库里这个特定文件组,内存OLTP是如何获得持久性的. 内存中O ...
- 内存中OLTP与内存不足
我已经写了好几次内存中OLTP的文章和”为什么我还不推荐内存中OLTP给用户”.今天我想进一步谈下内存中OLTP背后的内存需求,还有如果你内存不够的话会发生什么. 一切都与内存有关! 我们都知道很久之 ...
- 为什么我还不推荐内存中OLTP给用户
嗯,有些人在看玩这篇文章后会恨我,但我还是要说.1个月来我在内存中OLTP这个里领域里做了大量的工作,很多用户都请求使用这个惊艳的新技术.遗憾的是,关于内存中OLTP没有一个是真的令人激动的——看完你 ...
- 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...
随机推荐
- 【CUDA学习】共享存储器
下面简单介绍一些cuda中的共享存储器和全局存储器 共享存储器,shared memory,可以被同一块中的所有线程访问的可读写存储器,生存期是块的生命期. Tesla的每个SM拥有16KB共享存储器 ...
- js 生成笛卡尔积
其实生成 笛卡尔积的方法原本很简单,for循环就可以了, function discarts() { //笛卡尔积 var twodDscartes = function (a, b) { var r ...
- RPC和NFS
参考:http://eduunix.ccut.edu.cn/index2/html/linux/OReilly.SUSE.Linux.Jul.2006/059610183X/suselinux-CHP ...
- [转] Redis系统性介绍
Redis系统性介绍 http://blog.nosqlfan.com/html/3139.html?ref=rediszt 虽然Redis已经很火了,相信还是有很多同学对Redis只是有所听闻或者了 ...
- Git中当add错误的时候怎么办?
傻傻分不清楚. “git add .”是我常用的添加命令,添加完后来个“git status ”总是有那么几次发现有不想添加的东西.好多人用reset,nonono,这样不好会有个head错误爆出. ...
- 40页PPT勾画“互联网颠覆性思维”----诠释互联网思维
本文PPT内容涉及移动互联网的三个分支——移动电商.在线教育和新媒体. 不同领域一直是可以相互借鉴.相互渗透.相互学习的,在盈利模式和思维方式上有很多是共通的.
- Android定位&地图&导航——基于百度地图移动获取位置和自动定位
一.问题描述 使用百度地图实现如图所示应用,首先自动定位当前我起始位置(小圆点位置),并跟随移动不断自动定位我的当前位置 百度Api不同版本使用会有些差异,本例中加入lib如下: 二.编写MyAppl ...
- 编程语言 IDE 对比
IDE是集成开发环境的英文缩写,所谓集成开发环境,就是将你在开发过程中所需要的工具或功能集成到了一起,比如代码编写.分析.编译.调试等功能,从而最大化地提高开发者的工作效率. 每种编程语言都有一些特定 ...
- WPF的定时器
一.注意事项 引用命名空间:System.Windows.Threading.DispatcherTimer. 二.使用方法 var _timer = new DispatcherTimer(); _ ...
- IIS网站属性中没有ASP.NET选项
打开IIS6,右击属性,居然没有发现ASP.NET的配置选项,虽然好久没搞这个了,但是印象中绝对是有一个ASP.NET选项卡的.我很奇怪,我以为是.net framework 2.0没安装,下载下来安 ...