嗯,有些人在看玩这篇文章后会恨我,但我还是要说。1个月来我在内存中OLTP这个里领域里做了大量的工作,很多用户都请求使用这个惊艳的新技术。遗憾的是,关于内存中OLTP没有一个是真的令人激动的——看完你就知道了。

内存中OLTP有问题么?

没有!真的!我喜欢这个惊艳的新技术,但我还不能推荐它给任何用户。就这样!很有用户现在还运行在SQL Server 2008(R2)上,他们就想迁移到SQL Server 2014上。这个惊艳新技术给他们100倍的吞吐量提升。因此让我们来用它吧!遗憾的是并不简单。

很多人都问对于他们的工作量和环境,切换到SQL Server 2014是否有意义。基于我的建议,他们会做出持续至少5年的决定。因此这里我有巨大的责任。我要确保不会建议不能100%融入他们环境的技术。遗憾的是内存中OLTP不能融入99%的所有环境。

因此内存中OLTP有问题么,是什么我还不能推荐它给用户呢?我们开始分析……

没有外键

当微软首次向公众展示内存中OLTP时,它是很惊艳的:你切换开关,然后你的工作吞吐量就会快100倍。你只记住了立即走向右手边的针,不是么?但事实完全不一样。假设你有一个现存的数据库,你想要移动它的一些表到内存中OLTP。

这是不行的,因为内存中OLTP当前不支持外键(foreign keys)。非常希望你的数据库设计有引用完整性(referential integrity)。如果不是的话,请回到数据库基础设计,了解下引用完整性。这已是很多用户已经经历的最常见中断切换之一。他们喜欢迁移一些表到内存中OLTP,但他们不喜欢用它来丢失他们的引用完整性……

不能修改数据库架构

现在假设你同意在自己的表上不使用外键,你已经迁移它们到内存中OLTP。到目前还好。在你的内存优化表上如何处理架构修改呢?任何ALTER TABLE语句不被支持,你不能稍后创建任何额外可能需要的索引(哈希或范围索引)。当创建1个哈希索引,在表创建期间,你需要指定桶数。

这意味着你需要保护你的数据增长,还有随着时间过去你的数据如何改变。当你以后想要修改你的哈希桶数,因为你已意识到你有大量的哈希碰撞,你必须删掉你的内存优化表,然后再次重建。同时你如何处理你的数据?你必须转移它到另一个表,这样的话你不会丢失数据。这时你把数据存在哪里呢?用户如果这时还要访问这些数据怎么办?有很多的问题,但没有真正有用的答案……

没有执行计划

好,现在你用内存优化表很好,现在你想使用存储过程的本地编译功能。哇哦,现在好戏才开始!本地编译存储过程真的,真的非常快,因为你用本地机器码执行——C代码编译成汇编指令!太棒了!但是在查询执行期间是没有执行计划的,因为你只执行汇指令,不再执行那些传统缓慢解释后的执行计划。

当你执行遇到问题时,你怎么办?你不能看实际执行计划来认出问题。SQL Server只提供你估计计划,但估计计划不告诉你任何真实信息。它只是个估计,没别的。你真的想钻研生成的C代码来找出为什么本地编译存储过程这么慢?我不这么认为。

没有重编译

除了没有实际执行计划外,也没有重编译。但你的数据分布改变时,你还是用同样编译的执行计划。在执行期间本地编译存储过程不能重编译。我说过,在运行期间你只执行汇编指令——它们不能被重编译。

你如何摆脱这个问题?删除并重建你的存储过程,因为ALTER PROCEDURE语句不被支持。当你删除你的存储过程,你也会丢失所有授予的安全许可。你真的想丢失它们?另外,你的本地编译存储过程必须用SCHEMABINDING创建。因此当你已经删除存储过程本身时,你才可以删除你的内存优化表(例如,当你想修改哈希桶数时)。偶滴神啊……

本地编译的业务逻辑

这是我喜欢之一:在用本地编译的存储过程里运行复杂的CPU密集的业务逻辑。哇噢,我喜欢你有的那个大钱包!在SQL Server里运行复杂的CPU密集的业务逻辑是你可以有的最昂贵想法之一。在企业版SQL Server里,SQL Server是以每核心7000刀授权。因为我不想在SQL Server里运行任何CPU密集的工作!那一点也不经济。当然从微软角度来说这个很有意义。

如果在SQL Server里你有一些复杂CPU密集的业务逻辑,把它移到应用服务器(例如,Web服务器),因为1个应用服务器授权是完全不同的——非常便宜。你主要会有架构问题,没别的。我从不在SQL Server内部运行业务逻辑。

“对于每个人,640K应该足够了”

哈哈,那是我计算机发展史里最喜欢的名言之一。遗憾的是他说错了,当你看这篇文章时,看看用的电脑硬件时就会发现。当你使用内存中OLTP时,你需要大量的内存。微软建议内存大小为你内存优化表大小的2倍,例如对于150GB大小的表,你需要300GB的内存。另外的内存用做内存中OLTP内存使用的行版本控制。现在假设下,当你删除你的表,同时你想转移数据到另一个内存优化表:在这个情况下你应该有近600GB的内存!准备好了么?

关于OLTP

人们会问我,为什么我对这个惊艳的新技术如此否定。不是的,我并非否定,我只想告诉你事情的2面性,这样的话你可以做出正确的决定。

另外一些人告诉我内存中OLTP如此酷,因为它可以用作ETL过程里的分段表(staging table),并且我们不需要SQL Server里的临时表。哎呦!我们在慢慢拼写下这个技术的名称——非常慢:内存中O-L-T-P!它是关于OLTP——在线事务处理(Online Transaction Processing)。当然在其它场景也可以使用,但主焦点应该是OLTP场景!好好考虑下它。如果你当前有临时表的问题,那就在工作量上下文章,尝试在你临时表上减少工作量的压力。在性能调优里我经常提到:我们的终极目标是解决潜在的问题根源,不是为它创建一个解决方案。(例如当你看到 CXPACKET等待时,设置MAXDOP为1即可)

小结

内存中OLTP是个惊艳的新技术。但目前只实现了雏形。有太多的限制刚好阻止了大量人们在生产环境中使用它。在这篇文章里我已经概括了这些限制中的部分,这样的话你就可以重新考虑下是否想把内存中OLTP引入你的特定场景。

我很期待在SQL Server里的下个版本再次讨论这个话题,在一个图表里剔除那些无关的条目,因为微软已经移除了这些限制。这个惊艳技术还是由微软来决定往前发展的

感谢关注!

参考文章:

https://www.sqlpassion.at/archive/2015/03/11/dont-yet-recommend-memory-oltp-customers/

为什么我还不推荐内存中OLTP给用户的更多相关文章

  1. 内存中OLTP与内存不足

    我已经写了好几次内存中OLTP的文章和”为什么我还不推荐内存中OLTP给用户”.今天我想进一步谈下内存中OLTP背后的内存需求,还有如果你内存不够的话会发生什么. 一切都与内存有关! 我们都知道很久之 ...

  2. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  3. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  4. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  5. SQL Server 内存中OLTP内部机制概述(四)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  6. SQL Server 内存中OLTP内部机制概述(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  7. SQL Server 内存中OLTP内部机制概述(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  8. SQL Server 内存中OLTP内部机制概述(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  9. 配置内存中OLTP文件组提高性能

    在今天的文章里,我想谈下使用内存中OLTP的内存优化文件组来获得持久性,还有如何配置它来获得高性能.在进入正题前,我想简单介绍下使用你数据库里这个特定文件组,内存OLTP是如何获得持久性的. 内存中O ...

随机推荐

  1. 三步将Node应用部署到Heroku上

    Heroku是一个提供快速部署服务的云平台.支持Node,Ruby,Java,PHP,Python,Go多种语言,今天体验了下,简直不要太爽.下面简单的介绍一下. 首先还是要注册一个账号:https: ...

  2. MongoDB-基础-limit-skip-sort

    MongoDB Limit() 方法 如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的 ...

  3. ASP.NET Core中的ActionFilter与DI

    一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或 ...

  4. ASP.NET Core开发-Docker部署运行

    ASP.NET Core开发Docker部署,.NET Core支持Docker 部署运行.我们将ASP.NET Core 部署在Docker 上运行. 大家可能都见识过Docker ,今天我们就详细 ...

  5. Devexpress WPF Theme Editor 01

    在Devexpress中,已经有内置了很多主题样式.一般我们开发就已经够用了.但是随着客户的需求提高..我们要自己手动写一些样式这些的, 那么Devexpress 已经提供一个专门这样的工具. 下载地 ...

  6. 零基础如何学习java更有效呢?

    零基础学java,不知道该如何入手?也不知道学习的方向,很多人会问零基础怎么样学习,有没有什么入门的书籍推荐:只要方法正确,零基础学好java也是有机会的哦. 一.理解Java思想 Java是一门面向 ...

  7. 高性能 Socket 组件 HP-Socket v3.1.3 正式发布

    HP-Socket 是一套通用的高性能 Windows Socket 组件,提供服务端组件(IOCP 模型)和客户端组件(Event Select 模型),广泛适用于 Windows 平台的 TCP/ ...

  8. 最短路径——Floyd-Warshall算法

    Floyd-Warshall算法,简称Floyd算法,用于求解任意两点间的最短距离,时间复杂度为O(n^3). 我们平时所见的Floyd算法的一般形式如下: void Floyd() { int i, ...

  9. Java Class.cast方法

    1.Java api public T cast(Object obj); Casts an object to the class or interface represented 解释的比较笼统, ...

  10. (原)3.3 Zookeeper应用 - 负载均衡

    本文为原创文章,转载请注明出处,谢谢 负载均衡 1.原理 服务端启动创建临时节点(下图中servers下节点),临时节点数据包含负载信息 客户端启动获取服务器列表,并根据负载去连接一个负载较轻的服务器 ...