嗯,有些人在看玩这篇文章后会恨我,但我还是要说。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. c#和Javascript中去重总结

    一.前言 去重在我们的开发过程中经常遇到,避免重复元素的添加,我们需要对获取到的集合(包括List.Array等) 做相关的过滤操作.确保对象的唯一性,从而达到保证数据不冗余重复.由于自己是做.net ...

  2. Apache 创建虚拟主机目录和设置默认访问页面

    虚拟主机 (Virtual Host) 是在同一台机器搭建属于不同域名或者基于不同 IP 的多个网站服务的技术. 可以为运行在同一物理机器上的各个网站指配不同的 IP 和端口, 也可让多个网站拥有不同 ...

  3. .NET编码解码(HtmlEncode与HtmlEncode)

    编码代码: System.Web.HttpUtility.HtmlEncode("<a href=\"http://hovertree.com/\">何问起& ...

  4. Java实现Mysql数据库自动备份

    最近项目中有一个这样的需求,要求定时备份数据库.看了一些网上的资料,了解到主要思路是是使用java中的Runtime类的exec()方法,可以直接调用windows的cmd命令,参数就是Mysql的备 ...

  5. php实现设计模式之 职责链模式

    <?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...

  6. REST服务介绍二

           之前一篇文章写过REST服务介绍, 今天再次来自回顾一下. REST是一种架构风格. 首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是 HTTP 规范 ...

  7. Singleton(单例模式)

    一. /** * lazy man(不是线程安全的) * @author TMAC-J * */ public class Singleton { private static Singleton i ...

  8. UML(Unified Modeling Language)统一建模语言

    什么是模型 模型是对现实的简化 模型是提供系统的蓝图,模型可是包括详细计划.也可是是从更高程度考虑系统的总体计划,每个系统可以从不同的方面用不通过的模型来描述.因而每个模型都是在语义上闭合的抽象系统. ...

  9. 【grunt第二弹】30分钟学会使用grunt打包前端代码(02)

    前言 上一篇博客,我们简单的介绍了grunt的使用,一些基础点没能覆盖,我们今天有必要看看一些基础知识 [grunt第一弹]30分钟学会使用grunt打包前端代码 配置任务/grunt.initCon ...

  10. 认识DOM和一些方法

    认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...