{"id":145,"date":"2016-03-10T14:23:45","date_gmt":"2016-03-10T14:23:45","guid":{"rendered":"https:\/\/sqldoubleg.live-website.com\/?p=145"},"modified":"2016-03-10T15:00:57","modified_gmt":"2016-03-10T15:00:57","slug":"sql-server-2016-playing-with-database-scoped-configurations","status":"publish","type":"post","link":"https:\/\/www.sqldoubleg.com\/es\/2016\/03\/10\/sql-server-2016-playing-with-database-scoped-configurations\/","title":{"rendered":"SQL Server 2016, playing with DATABASE SCOPED CONFIGURATIONS"},"content":{"rendered":"<p>It&#8217;s been a few days since SQL Server 2016 RC0 was released and one of things people have blogged about is the new DATABASE SCOPED CONFIGURATIONS, where you can do modify certain behaviors at database level that before were only possible at server level, like the MAXDOP option.&nbsp;It&#8217;s been a few days since SQL Server 2016 RC0 was released and one of things people have blogged about is the new <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/mt629158.aspx\" target=\"_blank\">DATABASE SCOPED CONFIGURATIONS<\/a>, where you can do modify certain behaviors at database level that before were only possible at server level, like the MAXDOP option.<\/p>\n<p>Also you can take advantage of new features but keep using the old cardinality estimator (prior 2014 version) by setting LEGACY_CARDINALITY_ESTIMATION at database level. Before this change you could always use a compatibility level for the database up to SQL 2012 (110), but this is way cooler!<\/p>\n<p>So after reading a few posts, I was wondering how the new SQL Server would behave when you write a cross database query and those settings conflict to each other, so I rolled up my sleeves and prepare this demo to find out.<\/p>\n<p>Before start and considering the thing I wanted to test the most was about parallelism, I needed to get the [AdventureWorks2016CTP3] database big enough for the optimizer to come up with parallel plans if possible, so I used the script created by Adam Machanic (<a href=\"http:\/\/sqlblog.com\/blogs\/adam_machanic\/default.aspx\" target=\"_blank\">blog<\/a>|<a href=\"https:\/\/twitter.com\/AdamMachanic\" target=\"_blank\">twitter<\/a>) to grow the database, you can find it <a href=\"http:\/\/sqlblog.com\/blogs\/adam_machanic\/archive\/2011\/10\/17\/thinking-big-adventure.aspx\" target=\"_blank\">here<\/a><\/p>\n<p>Also I adapted the script to do the same in the [AdventureWorskDW2016CTP3] as I would use them both to do cross database queries and have different set up for each of them.<\/p>\n<p>Once it&#8217;s done, let&#8217;s go for it!<\/p>\n<p>This first query, when using the new cardinality estimator does not need to go parallel<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- this does NOT go parallel, with the NEW cardinality estimation\r\nUSE AdventureWorks2016CTP3\r\n\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = OFF\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0\r\nGO\r\n\r\nSELECT * \r\n\tFROM dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN dbo.bigProduct AS p\r\n\t\t\tON p.ProductID = th.ProductID\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/01_new_cardinality_no_parallel_plan.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/01_new_cardinality_no_parallel_plan.png\" alt=\"01_new_cardinality_no_parallel_plan\" width=\"413\" height=\"223\" class=\"aligncenter size-full wp-image-146\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/01_new_cardinality_no_parallel_plan.png 413w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/01_new_cardinality_no_parallel_plan-300x162.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/01_new_cardinality_no_parallel_plan-150x81.png 150w\" sizes=\"(max-width: 413px) 100vw, 413px\" \/><\/a><\/p>\n<p>But if we want to use the LEGACY_CARDINALITY_ESTIMATION, then it will generate a parallel plan&#8230;<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- this goes  parallel, with the OLD cardinality estimation\r\nUSE AdventureWorks2016CTP3\r\n\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0\r\nGO\r\n\r\nSELECT * \r\n\tFROM dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN dbo.bigProduct AS p\r\n\t\t\tON p.ProductID = th.ProductID\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\n\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/02_old_cardinality_parallel_plan.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/02_old_cardinality_parallel_plan.png\" alt=\"02_old_cardinality_parallel_plan\" width=\"565\" height=\"238\" class=\"aligncenter size-full wp-image-147\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/02_old_cardinality_parallel_plan.png 565w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/02_old_cardinality_parallel_plan-300x126.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/02_old_cardinality_parallel_plan-150x63.png 150w\" sizes=\"(max-width: 565px) 100vw, 565px\" \/><\/a><\/p>\n<p>So far so good, the same query behaves differently with each cardinality estimator, that was the plan I guess.<\/p>\n<p>Furthermore, if we want to use the old estimation but we don&#8217;t want to go parallel, the MAXDOP will do that for us (set to 1)<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- this does NOT go parallel, with the OLD cardinality estimation, but MAXDOP = 1\r\nUSE AdventureWorks2016CTP3\r\n\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 1\r\nGO\r\n\r\nSELECT * \r\n\tFROM dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN dbo.bigProduct AS p\r\n\t\t\tON p.ProductID = th.ProductID\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/03_old_cardinality_MAXDOP_1_no_parallel_plan.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/03_old_cardinality_MAXDOP_1_no_parallel_plan.png\" alt=\"03_old_cardinality_MAXDOP_1_no_parallel_plan\" width=\"426\" height=\"239\" class=\"aligncenter size-full wp-image-148\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/03_old_cardinality_MAXDOP_1_no_parallel_plan.png 426w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/03_old_cardinality_MAXDOP_1_no_parallel_plan-300x168.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/03_old_cardinality_MAXDOP_1_no_parallel_plan-150x84.png 150w\" sizes=\"(max-width: 426px) 100vw, 426px\" \/><\/a><\/p>\n<p>And then it&#8217;s time to start with the fun, joining the OLTP and the DW databases to see how that works, but first I&#8217;ll show you the query from the DW that goes parallel under the same settings as the OLTP<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n-- this goes parallel, with the OLD cardinality estimation\r\nUSE AdventureworksDW2016CTP3\r\nGO\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0\r\nGO\r\n\r\nSELECT * \r\n\tFROM dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN dbo.DimProductBig AS p\r\n\t\t\tON p.ProductKey = th.ProductKey\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/04_old_cardinality_DW_query_parallel_plan.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/04_old_cardinality_DW_query_parallel_plan.png\" alt=\"04_old_cardinality_DW_query_parallel_plan\" width=\"649\" height=\"242\" class=\"aligncenter size-full wp-image-149\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/04_old_cardinality_DW_query_parallel_plan.png 649w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/04_old_cardinality_DW_query_parallel_plan-300x112.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/04_old_cardinality_DW_query_parallel_plan-150x56.png 150w\" sizes=\"(max-width: 649px) 100vw, 649px\" \/><\/a><\/p>\n<p>So what if one database is set to use MAXDOP 1 and the other to 0? let&#8217;s see<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\nUSE AdventureworksDW2016CTP3\r\nGO\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 1\r\nGO\r\n\r\nUSE AdventureWorks2016CTP3\r\n\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0\r\nGO\r\n\r\nUSE AdventureWorks2016CTP3\r\nGO\r\n\r\nSELECT * \r\n\tFROM AdventureWorks2016CTP3.dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN AdventureWorks2016CTP3.dbo.bigProduct AS p\r\n\t\t\tON p.ProductID = th.ProductID\r\n\t\tINNER JOIN AdventureworksDW2016CTP3.dbo.DimProductBig AS dp\r\n\t\t\tON dp.ProductKey = p.ProductID\r\n\t\tINNER JOIN AdventureworksDW2016CTP3.dbo.bigTransactionHistory AS th2\r\n\t\t\tON th2.ProductKey = dp.ProductKey\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel.png\" alt=\"06_cross_db_query_parallel\" width=\"1445\" height=\"253\" class=\"aligncenter size-full wp-image-150\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel.png 1445w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel-300x53.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel-1024x179.png 1024w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/06_cross_db_query_parallel-150x26.png 150w\" sizes=\"(max-width: 1445px) 100vw, 1445px\" \/><\/a><\/p>\n<p>In this case the query plan goes parallel, but how is that possible if one of the databases involved in the query is restricted to use only single thread plans?<\/p>\n<p>That&#8217;s got a proper explanation, I guess, and it is that the query is executed under one single context (scope) and in the query above is the database [AdventureWorks2016CTP3] which is the one that is set to go parallel if needed.<\/p>\n<p>If the same query with same database settings is executed on the scope of [AdventureworksDW2016CTP3] it will not go parallel. See it<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\nUSE AdventureworksDW2016CTP3\r\nGO\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 1\r\nGO\r\n\r\nUSE AdventureWorks2016CTP3\r\n\r\nALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON\r\nALTER DATABASE SCOPED CONFIGURATION SET MAXDOP = 0\r\nGO\r\n\r\nUSE AdventureworksDW2016CTP3\r\n\r\nSELECT * \r\n\tFROM AdventureWorks2016CTP3.dbo.bigTransactionHistory AS th\r\n\t\tINNER JOIN AdventureWorks2016CTP3.dbo.bigProduct AS p\r\n\t\t\tON p.ProductID = th.ProductID\r\n\t\tINNER JOIN AdventureworksDW2016CTP3.dbo.DimProductBig AS dp\r\n\t\t\tON dp.ProductKey = p.ProductID\r\n\t\tINNER JOIN AdventureworksDW2016CTP3.dbo.bigTransactionHistory AS th2\r\n\t\t\tON th2.ProductKey = dp.ProductKey\r\n\tWHERE p.Color = 'Black'\r\n\t\tAND th.TransactionDate &gt; DATEADD(YY, -1, GETDATE())\r\nGO\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/07_cross_db_query_no_parallel.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/03\/07_cross_db_query_no_parallel.png\" alt=\"07_cross_db_query_no_parallel\" width=\"806\" height=\"258\" class=\"aligncenter size-full wp-image-151\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/07_cross_db_query_no_parallel.png 806w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/07_cross_db_query_no_parallel-300x96.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2016\/03\/07_cross_db_query_no_parallel-150x48.png 150w\" sizes=\"(max-width: 806px) 100vw, 806px\" \/><\/a><\/p>\n<p>So in conclusion, all those new database settings are in use only when executing queries under the scope of the database, not just by simply using a table from that database, hence we must be careful to avoid surprises in the future when writing cross database queries.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s been a few days since SQL Server 2016 RC0 was released and one of things people have blogged about is the new DATABASE SCOPED CONFIGURATIONS, where you can do modify certain&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[7,29,28,23],"_links":{"self":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/145"}],"collection":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/comments?post=145"}],"version-history":[{"count":1,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/145\/revisions"}],"predecessor-version":[{"id":152,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/145\/revisions\/152"}],"wp:attachment":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/media?parent=145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/categories?post=145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/tags?post=145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}