{"id":1817,"date":"2017-08-09T08:33:33","date_gmt":"2017-08-09T07:33:33","guid":{"rendered":"http:\/\/andreas-wolter.com\/?p=1817\/"},"modified":"2017-10-25T10:01:41","modified_gmt":"2017-10-25T09:01:41","slug":"optimizing-workflows-with-in-memory-and-natively-compiled-objects","status":"publish","type":"post","link":"https:\/\/andreas-wolter.com\/en\/optimizing-workflows-with-in-memory-and-natively-compiled-objects\/","title":{"rendered":"Optimizing workflows with In-Memory and Natively Compiled Objects &#8211; or how it does not work"},"content":{"rendered":"\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_heading-80c352a1ef174d4d20a1e22cbbeac0c1\">\n#top .av-special-heading.av-av_heading-80c352a1ef174d4d20a1e22cbbeac0c1{\npadding-bottom:10px;\n}\nbody .av-special-heading.av-av_heading-80c352a1ef174d4d20a1e22cbbeac0c1 .av-special-heading-tag .heading-char{\nfont-size:25px;\n}\n.av-special-heading.av-av_heading-80c352a1ef174d4d20a1e22cbbeac0c1 .av-subheading{\nfont-size:18px;\n}\n<\/style>\n<div  class='av-special-heading av-av_heading-80c352a1ef174d4d20a1e22cbbeac0c1 av-special-heading-h3 blockquote modern-quote  avia-builder-el-0  el_before_av_textblock  avia-builder-el-first '><h3 class='av-special-heading-tag'  itemprop=\"headline\"  >Optimizing workflows with In-Memory and Natively Compiled Objects in SQL Server <\/h3><div class='av-subheading av-subheading_below'><p>\u2013 or how it does not work<\/p>\n<\/div><div class=\"special-heading-border\"><div class=\"special-heading-inner-border\"><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>During the course of optimizing data-access-code with the In-Memory-functionalities in Microsoft SQL Server (memory optimized tables + indexes, memory optimized table valued parameters and natively compiled stored procedures), you may often realize that sometimes you go one step forward and then another one backwards.<!--more--><\/p>\n<p>As often: the devil is in the details.<\/p>\n<p>Take the <strong>sample-scenario <\/strong>of a stored procedure that has a <strong>workflow<\/strong> that can be summed up like the following:<\/p>\n<ol>\n<li>Create a Temporary Table (#)<\/li>\n<li>Insert a batch of data, ~200,000 rows<\/li>\n<li>Update the Temptable using a join to another (disk-based) table (Dimension)<\/li>\n<li>Update the Temptable further<\/li>\n<li>Delete some rows<\/li>\n<li>Insert the remaining data into a Target-Table (Fact) (disk-based)<\/li>\n<\/ol>\n<p>That pattern is not so uncommon in ETL-scenarios, when loading data into Datawarehouse Fact-tables, but can be used in many other contexts.<\/p>\n<p>Now one could be tempted to <strong>improve performance using <u>Memory-Optimized<\/u> Table Valued Parameters (TVP)<\/strong> instead of the Temptable.<\/p>\n<ol>\n<li>Create a memory optimized TVP (@)<\/li>\n<li>Insert a batch of data, ~200,000 rows<\/li>\n<li>Update the TVP using join to the other disk-based table<\/li>\n<li>Update the TVP further<\/li>\n<li>Delete some rows<\/li>\n<li>Insert the remaining data into a Target-Table (disk-based)<\/li>\n<\/ol>\n<p>The idea behind is that in the XTP-engine one can work without Locks, even without latches, and in certain scenarios even further without any IO. (Here a bit more on that: <a href=\"http:\/\/www.insidesql.org\/blogs\/andreaswolter\/2016\/07\/the-sql-server-2016-in-memory-evolution-from-row-store-to-columnstore-to-in-memory-operational-analytics\" target=\"_blank\" rel=\"noopener\">The SQL Server 2016 In-Memory Evolution \u2013 from row-store to columnstore to in-memory operational analytics<\/a>, <a href=\"http:\/\/www.insidesql.org\/blogs\/andreaswolter\/2016\/11\/sql-server-2016-sp1-removes-programmability-feature-limits\" target=\"_blank\" rel=\"noopener\">SQL Server 2016 SP1 removes the editions\u2019 programming feature limits! Everything from Always Encrypted to XTP\/In-memory for everybody!<\/a>)<\/p>\n<p>The concept would be to simply <strong>replace the Temporary Table with a Memory Optimized TVP<\/strong>.<\/p>\n<p>But the outcome might floor you: It may or even may not get a bit faster \u2013 or even a bit slower!<\/p>\n<p>If there is a second table involved (i.e. Join a dimension), then maybe we need to <strong>get that second table memory optimized as well<\/strong>.<\/p>\n<p>But still in my case you will see, <strong>it even becomes slower again<\/strong>!<\/p>\n<p>The problem lies, among other things, in the amount of locking, that is still involved:<\/p>\n<\/div><\/section>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_image-1442b2211ce230ceba852e70ad1f2f03\">\n.avia-image-container.av-av_image-1442b2211ce230ceba852e70ad1f2f03 img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-av_image-1442b2211ce230ceba852e70ad1f2f03 .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-av_image-1442b2211ce230ceba852e70ad1f2f03 av-styling- avia-align-center  avia-builder-el-2  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-2390 avia-img-lazy-loading-not-2390 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1.jpg\" alt='' title='1708_Lock_Comparison_InMemory'  height=\"332\" width=\"957\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1.jpg 957w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1-600x208.jpg 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1-300x104.jpg 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1-768x266.jpg 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1-705x245.jpg 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Comparison_InMemory-1-450x156.jpg 450w\" sizes=\"(max-width: 957px) 100vw, 957px\" \/><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>Why on earth do we suddenly have MORE Locking by using memory optimized tables?<\/p>\n<p>The answer lies in the fact that <strong>in order to get the data into memory optimized tables, we still have to read them from the disk-based tables + write back <\/strong>in the end (in my case even supported by a Clustered Columnstore Index \u2013 in vain\u2026). Even more so\u00a0when the memory optimized table\/TVP is joining the still disk-based Dimension-table.<\/p>\n<\/div><\/section>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_image-0a14f14d620149f3cee1771544dba643\">\n.avia-image-container.av-av_image-0a14f14d620149f3cee1771544dba643 img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-av_image-0a14f14d620149f3cee1771544dba643 .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-av_image-0a14f14d620149f3cee1771544dba643 av-styling- avia-align-center  avia-builder-el-4  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-1822 avia-img-lazy-loading-not-1822 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution.jpg\" alt='' title='1708_Lock_Distribution'  height=\"290\" width=\"932\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution.jpg 932w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution-600x187.jpg 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution-300x93.jpg 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution-768x239.jpg 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution-705x219.jpg 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Lock_Distribution-450x140.jpg 450w\" sizes=\"(max-width: 932px) 100vw, 932px\" \/><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>If you disable or remove foreign keys during this process, you will see an equal performance improvement for all the tested approaches.<\/p>\n<p>So, in order <strong>to truly gain a noticeable performance improvement<\/strong>, unfortunately, in many cases, there is <strong>no \u201cquick win\u201d<\/strong>.<\/p>\n<p>This is because as described, the bottleneck \u201cdisk\u201d does not simply get removed, but still remains in Interop-Mode. All interactions between the In-Memory engine and the standard page-based engine slow your work down. So you really need to eliminate this as much as possible. This is why I sometimes will say: <strong><em>\u201cIn order to truly profit from In-Memory, you need to redesign your processes.\u201d<\/em><\/strong><\/p>\n<p>This means: <strong>Get your workflow and schema(!) as much as possible purely into In-Memory!<\/strong><\/p>\n<p>Once you have mastered this stage, you will be <strong>rewarded with the ability to use natively compiled stored procedures<\/strong>.<\/p>\n<p>By their very nature these cannot work with On-Disk\/pages-based tables and profit from extremely optimized compiled code, which will never be re-compiled unless you absolutely want it to.<\/p>\n<p>On the way to reaching that goal you will surely stumble upon one of the many still existing limitations of the XTP-engine, which does not support the same T-SQL surface as the for decades evolved standard engine.<\/p>\n<p>But this improves in every version. In SQL Server 2016 you will most likely be hindered by the Errors like:<\/p>\n<p style=\"padding-left: 30px;\">Msg 12311, Level 16, State 39, Procedure ProcedureName, Line 73 [Batch Start Line 11]<\/p>\n<p style=\"padding-left: 30px;\">Subqueries (queries nested inside another query) is only supported in SELECT statements with natively compiled modules.<\/p>\n<p style=\"padding-left: 30px;\">Msg 12319, Level 16, State 81, Procedure ProcedureName, Line 64 [Batch Start Line 11]<\/p>\n<p style=\"padding-left: 30px;\">Using the FROM clause in an UPDATE statement and specifying a table source in a DELETE statement is not supported with natively compiled modules.<\/p>\n<p style=\"padding-left: 30px;\">Msg 10775, Level 16, State 1, Procedure ProcedureName, Line 36 [Batch Start Line 11]<\/p>\n<p style=\"padding-left: 30px;\">Object &#8216;SchemaName.TableName&#8217; is not a memory optimized table or a natively compiled inline table-valued function and cannot be accessed from a natively compiled module.<\/p>\n<p style=\"padding-left: 30px;\">And some more\u2026<\/p>\n<p>Once you have overcome it with clever re-design, you will finally profit from the true potential of In-Memory, like the ~50% performance improvement in my sample ETL-workflow.<\/p>\n<p>The <strong>optimized workflow<\/strong> goes like this:<\/p>\n<ol>\n<li>Prepare a permanently available memory optimized table with SCHEMA_ONLY<\/li>\n<li>Insert the batch of data, before starting the natively compiled stored procedure\n<ul>\n<li>For the Insert already join the second table and integrate the necessary data\/columns to avoid a second Insert<\/li>\n<\/ul>\n<\/li>\n<li>Inside the natively compiled stored procedure Update the memory optimized table using simple statements without Subselects or Joins<\/li>\n<li>Delete some rows directly inside the proc<\/li>\n<li>Back outside of the natively stored proc Insert the remaining data into the Target-Table (disk-based)<\/li>\n<\/ol>\n<p>The limit is still the disk-based engine, as one can see in this query plan of the final code of the final Insert:<\/p>\n<\/div><\/section>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_image-4f9826641bcb975ddc741b7b359f9f6a\">\n.avia-image-container.av-av_image-4f9826641bcb975ddc741b7b359f9f6a img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-av_image-4f9826641bcb975ddc741b7b359f9f6a .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-av_image-4f9826641bcb975ddc741b7b359f9f6a av-styling- avia-align-center  avia-builder-el-6  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-1818 avia-img-lazy-loading-not-1818 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan.jpg\" alt='' title='1708_InMemoryQueryPlan'  height=\"412\" width=\"1307\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan.jpg 1307w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-600x189.jpg 600w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-300x95.jpg 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-768x242.jpg 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-1030x325.jpg 1030w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-705x222.jpg 705w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_InMemoryQueryPlan-450x142.jpg 450w\" sizes=\"(max-width: 1307px) 100vw, 1307px\" \/><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>The final results and performance comparison are as follows:<\/p>\n<\/div><\/section>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_image-83d461a4f4ec4bda9bcf43bb1dc9faaf\">\n.avia-image-container.av-av_image-83d461a4f4ec4bda9bcf43bb1dc9faaf img.avia_image{\nbox-shadow:none;\n}\n.avia-image-container.av-av_image-83d461a4f4ec4bda9bcf43bb1dc9faaf .av-image-caption-overlay-center{\ncolor:#ffffff;\n}\n<\/style>\n<div  class='avia-image-container av-av_image-83d461a4f4ec4bda9bcf43bb1dc9faaf av-styling- avia-align-center  avia-builder-el-8  el_after_av_textblock  el_before_av_textblock '   itemprop=\"image\" itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/ImageObject\" ><div class=\"avia-image-container-inner\"><div class=\"avia-image-overlay-wrap\"><img decoding=\"async\" class='wp-image-2514 avia-img-lazy-loading-not-2514 avia_image ' src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Perf_Comparison_InMemory2.jpg\" alt='' title='1708_Perf_Comparison_InMemory2'  height=\"415\" width=\"576\"  itemprop=\"thumbnailUrl\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Perf_Comparison_InMemory2.jpg 576w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Perf_Comparison_InMemory2-300x216.jpg 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2017\/08\/1708_Perf_Comparison_InMemory2-450x324.jpg 450w\" sizes=\"(max-width: 576px) 100vw, 576px\" \/><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>There is a lot more to investigate in such a POC, which goes beyond the purpose of this article.<\/p>\n<p>For example, one might notice the brutally increased amount of locking in Interop-Mode versus standard T-SQL \u2013 suspiciously identical to the number of rows being passed though\u2026<\/p>\n<p>I hope my dear readers take this as a motivation that while the path may be stony, one can get amazing results with the In-Memory engine in SQL Server. With the memory sizes that one can buy today for comparably little money (think 1.5TB per socket), I am waiting for the day that most data will simply be In-Memory from the outset. And those of you who learn about the new paradigms will be the first to profit from it.<\/p>\n<p>If you are in South-Asia this summer, you are welcome to come to my full day PreCon on In-Memory technologies in SQL Server at the Data Platform Summit in Bangalore, India, August 16<sup>th<\/sup>:<\/p>\n<p><a href=\"http:\/\/www.insidesql.org\/blogs\/andreaswolter\/2017\/07\/in-memory-technologies-in-sql-server-to-operational-analytics-master-at-data-platform-summit-2017-in-india-and-further-conferences-this-summer\" target=\"_blank\" rel=\"noopener\">One day of \u201eIn-Memory Technologies in SQL Server \u2013 From 0 to Operational Analytics Master\u201c at Data Platform Summit 2017 in Bangalore\/India and further conferences this summer<\/a><\/p>\n<p>Here a direct link: <a href=\"http:\/\/dataplatformgeeks.com\/dps2017\/pre-conference-seminars\/\" target=\"_blank\" rel=\"noopener\">http:\/\/dataplatformgeeks.com\/dps2017\/pre-conference-seminars\/<\/a><\/p>\n<p><strong>\u00a0<\/strong><\/p>\n<p>Happy memory-optimizing<\/p>\n<p>Andreas<\/p>\n<\/div><\/section>\r\n\r\n<div  class='hr av-av_hr-0ff602b3e980a3377077ff3c1c834df6 hr-default  avia-builder-el-10  el_after_av_textblock  el_before_av_one_full '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_one_full-97c650ae075063b375f558a776c570f8\">\n#top .flex_column.av-av_one_full-97c650ae075063b375f558a776c570f8{\nmargin-top:40px;\nmargin-bottom:40px;\n}\n.flex_column.av-av_one_full-97c650ae075063b375f558a776c570f8{\nborder-radius:0px 0px 0px 0px;\npadding:0px 0px 0px 0px;\n}\n.responsive #top #wrap_all .flex_column.av-av_one_full-97c650ae075063b375f558a776c570f8{\nmargin-top:40px;\nmargin-bottom:40px;\n}\n<\/style>\n<div  class='flex_column av-av_one_full-97c650ae075063b375f558a776c570f8 av_one_full  avia-builder-el-11  el_after_av_hr  el_before_av_social_share  first flex_column_div av-zero-column-padding  '     ><section  class='av_textblock_section av-av_textblock-2de302bf1aa3cf4c9157dbe6f50ac7eb '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><div><\/div>\n<div><\/div>\n<\/div><\/section><\/div>\r\n\r\n<div  class='av-social-sharing-box av-av_social_share-8644d330ffb238fff0cfa858c5295467 av-social-sharing-box-default  avia-builder-el-13  el_after_av_one_full  el_before_av_hr  av-social-sharing-box-fullwidth'><div class=\"av-share-box\"><h5 class='av-share-link-description av-no-toc '>Share<\/h5><ul class=\"av-share-box-list noLightbox\"><li class='av-share-link av-social-link-facebook' ><a target=\"_blank\" aria-label=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https:\/\/andreas-wolter.com\/en\/optimizing-workflows-with-in-memory-and-natively-compiled-objects\/&#038;t=Optimizing%20workflows%20with%20In-Memory%20and%20Natively%20Compiled%20Objects%20%E2%80%93%20or%20how%20it%20does%20not%20work\" aria-hidden=\"false\" data-av_icon=\"\ue8f3\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Facebook\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Facebook<\/span><\/a><\/li><li class='av-share-link av-social-link-twitter' ><a target=\"_blank\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=Optimizing%20workflows%20with%20In-Memory%20and%20Natively%20Compiled%20Objects%20%E2%80%93%20or%20how%20it%20does%20not%20work&#038;url=https:\/\/andreas-wolter.com\/en\/?p=1817\" aria-hidden=\"false\" data-av_icon=\"\ue8f1\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Twitter\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Twitter<\/span><\/a><\/li><li class='av-share-link av-social-link-linkedin' ><a target=\"_blank\" aria-label=\"Share on LinkedIn\" href=\"https:\/\/linkedin.com\/shareArticle?mini=true&#038;title=Optimizing%20workflows%20with%20In-Memory%20and%20Natively%20Compiled%20Objects%20%E2%80%93%20or%20how%20it%20does%20not%20work&#038;url=https:\/\/andreas-wolter.com\/en\/optimizing-workflows-with-in-memory-and-natively-compiled-objects\/\" aria-hidden=\"false\" data-av_icon=\"\ue8fc\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on LinkedIn\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on LinkedIn<\/span><\/a><\/li><\/ul><\/div><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-av_hr-4474f20d2389e2e5ecf918a02da5132e\">\n#top .hr.hr-invisible.av-av_hr-4474f20d2389e2e5ecf918a02da5132e{\nheight:50px;\n}\n<\/style>\n<div  class='hr av-av_hr-4474f20d2389e2e5ecf918a02da5132e hr-invisible  avia-builder-el-14  el_after_av_social_share  el_before_av_comments_list '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n<div  class='av-buildercomment av-av_comments_list-88ce68e426f11248fa394058a3de040f  av-blog-meta-author-disabled av-blog-meta-html-info-disabled'><\/div>","protected":false},"excerpt":{"rendered":"During the course of optimizing data-access-code with the In-Memory-functionalities in Microsoft SQL Server (memory optimized tables + indexes, memory optimized table valued parameters and natively compiled stored procedures), you may often realize that sometimes you go one step forward and then another one backwards.","protected":false},"author":4,"featured_media":2213,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,42,43,45,44],"tags":[],"class_list":["post-1817","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-in-memory-oltpxtp-htap","category-locking-blocking","category-performance","category-sql-server-2016","category-storage-engine"],"_links":{"self":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/1817","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/comments?post=1817"}],"version-history":[{"count":29,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/1817\/revisions"}],"predecessor-version":[{"id":5819,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/1817\/revisions\/5819"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media\/2213"}],"wp:attachment":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media?parent=1817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/categories?post=1817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/tags?post=1817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}