<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>SQL Database Engine Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/feed.xml</link>
    <description>This is the blog of the engineering team managing and developing the Database Engine for SQL Server and Azure SQL Database</description>
    <lastBuildDate>Fri, 29 Mar 2019 04:08:08 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Our new Azure SQL Database blog site is live</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/our-new-azure-sql-database-blog-site-is-live</link>
      <pubDate>Thu, 28 Mar 2019 21:08:08 GMT</pubDate>
      <dc:creator><![CDATA[Ajay.MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8735</guid>
      <description><![CDATA[Follow us in our new blog site going...]]></description>
      <content:encoded><![CDATA[Follow us in our new blog site going forward:
https://techcommunity.microsoft.com/t5/Azure-SQL-Database/bg-p/Azure-SQL-Database
]]></content:encoded>
    </item>
    <item>
      <title>Identify log write limits on Azure SQL Managed Instance using QPI library</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/identify-log-write-limits-on-azure-sql-managed-instance-using-qpi-library</link>
      <pubDate>Mon, 11 Mar 2019 07:12:34 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8625</guid>
      <description><![CDATA[Azure SQL Managed Instance is fully managed SQL Server instance hosted in Azure cloud. Managed...]]></description>
      <content:encoded><![CDATA[Azure SQL Managed Instance is fully managed SQL Server instance hosted in Azure cloud. Managed Instance introduces some limits such as max log write throughput that can slow down your workload. In this post you will see how to identify write log throughput issue on Managed Instance.<!--more-->

Azure SQL Managed Instance has several <a href="https://docs.microsoft.com/en-us/azure/sql-database/sql-database-managed-instance-resource-limits#service-tier-characteristics">built-in resource limits</a> such as max log write rate. The reason for introducing this log write limit is the necessity to ensure that log backups can catch-up incoming data.

In this post, I'm using QPI library to easily analyze wait statistics on Managed Instance. <span>To install QPI library go to </span><a href="https://github.com/JocaPC/qpi#installation">the installation section</a><span> and download the SQL script for your version of SQL Server (it supports Azure SQL/SQL Server 2016+ because it depends on Query Store views).</span>
<blockquote>Disclaimer: QPI library is open source library provided as-is and not maintained by Microsoft. There are not guarantees that the results are correct and that there are not bugs in calculations. This is a helper library that can help you to more easily analyze performance of your Managed Instance, but you can do the same job by looking directly at DMVs.</blockquote>
With this library, I can easily take a snapshot of wait statistics, wait some time and read the wait statistics values:
<pre>exec qpi.snapshot_wait_stats;

waitfor delay '00:00:03';

select *
from qpi.wait_stats
order by wait_time_s desc;
</pre>
Example of the result returned by this query is shown below:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/wait-stats.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/wait-stats-1024x228.png" alt="" width="879" height="196" class="alignnone size-large wp-image-8435" /></a>

In this example, you can see that the tasks on Managed Instance are waiting on INSTANCE_LOG_RATE_GOVERNOR wait type (with a link to the description of the wait type). You can go further and identify the queries that are causing these as it is described here: issues https://blogs.msdn.microsoft.com/sqlserverstorageengine/2019/03/05/analyzing-wait-statistics-on-managed-instance/

As an alternative, you can analyze IO performance on the Managed Instance to identify bottlenecks using the following procedure/view:
<ul>
 	<li>qpi.snapshot_file_stats procedure will take a snapshot of io statistics from sys.dm_io_virtual_file_stats DM function. You MUST take the snapshot because sys.dm_io_virtual_file_stats contains cumulative information and you need to calculate sample in the recent time interval.</li>
 	<li>qpi.file_stats view will get the file statistics since the last snapshot. This view contains several calculations such as IOPS, throughput based on a data from sys.dm_io_virtual_file_stats.</li>
</ul>
The following query will summarize write throughput (MB/s) and IOPS on the instance categorized per file types (LOG/DATA):

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/instance-io-stats.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/instance-io-stats.png" alt="" width="974" height="490" class="alignnone size-full wp-image-8635" /></a>

You can see in the result that my instance is using 47.5 MB/s writing in log file and 1226 IOPS in total. If you look at the description of  <a href="https://docs.microsoft.com/en-us/azure/sql-database/sql-database-managed-instance-resource-limits#service-tier-characteristics">resource limits</a> in Azure documentation, you will see that ~48MB/s is log rate limit that I'm hitting and this is the reason why I see dominant INSTANCE_LOG_RATE_GOVERNOR wait statistic.

This analysis tells you that you are running some log-write heavy operation that uses most of the write log - in this case I'm running several REBUILD INDEX operations.]]></content:encoded>
    </item>
    <item>
      <title>Running Azure CosmosDB queries from SQL Server using ODBC driver</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/running-azure-cosmosdb-queries-from-sql-server-using-odbc-driver</link>
      <pubDate>Mon, 11 Mar 2019 03:45:01 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8575</guid>
      <description><![CDATA[Azure CosmosDB provides ODBC driver that enables you to query CosmosDB collections like classic...]]></description>
      <content:encoded><![CDATA[Azure CosmosDB provides ODBC driver that enables you to query CosmosDB collections like classic databases. In this post you will see how to query CosmosDB collections from Sql Server using Transact-Sql.

<!--more-->

Why querying CosmosDB from SQL Server? Cosmos DB enables you to store documents and other non-relational types of data and provides SQL/API that enables you to fetch, filter, and sort results. However, in some cases, you would need to run more complex queries that have GROUP BY, HAVING, analytical functions, or to join your non-relational data from CosmosDB with data that you are storing in SQL Server tables. In that case, you might want to leverage full power of TransactSQL to query data in Cosmos DB.
<h2>Cosmos DB setup</h2>
First you need to setup CosmosDB account and add some documents to your collections. I have created CosmosDB account called <strong>odbc</strong>, with database <strong>WWI</strong> and collection <strong>Orders</strong>, and added three documents:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDb.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDb-1024x510.png" alt="" width="879" height="438" class="alignnone size-large wp-image-8585" /></a>

I'm accessing this collection using SQL API.
<h2>Driver setup</h2>
Now you need to install ODBC Driver for CosmosDB on the computer where you have SQL Server installed. I'm using <a href="https://aka.ms/cosmos-odbc-64x64">Microsoft Azure Cosmos DB ODBC 64-bit.msi</a><span> </span>for 64-bit Windows - 64-bit versions of Windows 8.1 or later, Windows 8, Windows 7, Windows Server 2012 R2, Windows Server 2012, and Windows Server 2008 R2.

Once you install this driver, you should setup ODBC source in system DSN and test the connection:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDbOdbcSource.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDbOdbcSource-1024x575.png" alt="" width="879" height="494" class="alignnone size-large wp-image-8595" /></a>
<h2>Querying CosmosDB</h2>
Once you setup everything, you can use classic OPENROWSET function to query CosmosDB data by specifying CosmosDB DSN in the connection:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDbResults.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/BP1-AzureCosmosDbResults-1024x283.png" alt="" width="879" height="243" class="alignnone size-large wp-image-8605" /></a>

As a results you will get three rows representing three documents in CosmosDB. Missing fields will be returned as NULL. You can also filter results based on some criterion like:
<pre>SELECT a.*
FROM OPENROWSET('MSDASQL', 
'DSN=cosmosdb1', 
'select * from Orders where billto_Name = ''John Smith''') as a</pre>
One interesting thing that you need to be aware is that complex JSON objects such as <strong>shipTo</strong> or <strong>billTo</strong> from the first image are flattened and every field is returned in the format &lt;object name&gt;_&lt;field name&gt;. You should be aware of this if you expected to have sub-objects as-is. Also, in my case, array properties such as tags are not mapped/returned.
<h2>Conclusion</h2>
ODBC Driver for Cosmos DB is enables you to run Transact-SQL queries on CosmosDb data, which might be useful if you need rich data analytic on remote data stored in CosmosDB. In this case, you can send query to CosmosDB with predicate that will filter the results, select only the fields that you need and then do rich-analysis on SQL Server using full Transact-SQL language.

Note that this is possible only on SQL Server and not in Azure SQL Database because CosmosDb driver is not installed on Azure SQL and you cannot add your own drivers. If you are interested for this feature on Azure SQL you can send the idea on feedback for <a href="https://feedback.azure.com/forums/217321-sql-database" title="View all ideas in SQL Database">SQL Database</a> or <a href="https://feedback.azure.com/forums/915676-sql-managed-instance" title="View all ideas in SQL Managed Instance">SQL Managed Instance</a>.]]></content:encoded>
    </item>
    <item>
      <title>Monitor local storage usage on General Purpose Azure SQL Managed Instance</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/monitor-storage-local-storage-usage-on-general-purpose-managed-instance</link>
      <pubDate>Fri, 08 Mar 2019 08:30:55 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8535</guid>
      <description><![CDATA[Azure SQL Managed Instance has predefined storage space that depends on the values of reserved...]]></description>
      <content:encoded><![CDATA[Azure SQL Managed Instance has predefined storage space that depends on the values of reserved storage and vCores that you choose when you provision the instance. In this post you will see how to monitor storage space on the Managed Instance.

<!--more-->

In Managed Instance you can reach three storage limits:
<ul>
 	<li>Storage limit of managed instance that you choose on the portal. This limit cannot be bigger than 8TB in General Purpose or 4TB in Business Critical. In <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2019/03/06/sending-resource-alerts-on-managed-instance-using-db_mail/">this post</a> you can find how to check storage usage and create alerts using SQL Agent.</li>
 	<li>(General Purpose only) Allocation limit of underlying remote Azure premium storage which is described <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/08/20/reaching-azure-disk-storage-limit-on-general-purpose-azure-sql-database-managed-instance/">here</a>.</li>
</ul>
<ul>
 	<li>(General Purpose only) the storage limit of local SSD disk storage - in Managed Instance tempdb is placed in local SSD that can have 24GB*&lt;number of vCores&gt; space. If you reach this limit, you would not be able to create temporary objects in tempdb.</li>
</ul>
If you reach the storage limit, you would need to increase the storage space/number of vCores or to free some resources. It is important to add more storage before you reach the limits, because changing storage is done using upgrade service tier operation that can take few hours.

sys.dm_os_volume_stats provide information about the volumes including total and used storage on the Managed Instance. You can find storage information using the following query:
<pre>SELECT volume_mount_point,
used_gb = CAST(MIN(total_bytes / 1024. / 1024 / 1024) AS NUMERIC(8,1)),
available_gb = CAST(MIN(available_bytes / 1024. / 1024 / 1024) AS NUMERIC(8,1)),
total_gb = CAST(MIN((total_bytes+available_bytes) / 1024. / 1024 / 1024) AS NUMERIC(8,1))
FROM sys.master_files AS f 
CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id)
GROUP BY volume_mount_point;</pre>
If you execute this query, it will return you amount of total, available and used storage on remote azure premium storage and local SSD:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/monitor-volume.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/monitor-volume-1024x408.png" alt="" width="879" height="350" class="alignnone size-large wp-image-8555" /></a>

In this case, I have 8-core instance that has 8*24GB = 192GB of local SSD storage shown as c:\WFRoot\ volume. https:// volume shows how much storage you ar eusing on remote Azure Premium Disk storage.

You should periodically monitor results of this query and react if you see that available_gb is decreasing, because you might get out of the space.

You can also create SQL Agent Job that will periodically run this query and send you a warning using db_mail if you will reach the maximum storage space. In <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2019/03/06/sending-resource-alerts-on-managed-instance-using-db_mail/">this post</a> you can find how to check remote storage usage and create alerts using SQL Agent so you can use the similar approach with the local storage.

&nbsp;

&nbsp;

&nbsp;

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/monitor-storage.png"></a>]]></content:encoded>
    </item>
    <item>
      <title>Sending resource alerts on Managed Instance using db_mail</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/sending-resource-alerts-on-managed-instance-using-db_mail</link>
      <pubDate>Wed, 06 Mar 2019 07:10:52 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8465</guid>
      <description><![CDATA[One of the biggest issue that you might experience in Managed Instance is reaching storage limit or...]]></description>
      <content:encoded><![CDATA[One of the biggest issue that you might experience in Managed Instance is reaching storage limit or finding out that you don't have enough CPU. In this case you would need to get the bigger instance; however, this is not instant operation. In this post, you will see how you can monitor resource usage and send email alerts if there is a risk that you might reach the limits.

<!--more-->

Azure SQL Managed Instance enables you to define how much resources you want to provision in terms of max storage and max cores that can be used. If you reach the storage limit there are several issues that will happen:
<ul>
 	<li>Your databases are in "read-only" state because nothing can be written in log/data files.</li>
 	<li>Some of the read queries cannot run because they might require tempdb to grow to store some temporary objects.</li>
 	<li>CHECKPOINT cannot flush data from memory into mdf files.</li>
</ul>
Generally, this is the case that you want to avoid. Although you can always upgrade the service tier and get more storage or CPU, this is not an instant operation in Managed Instance because new a host VM must be provisioned and injected in your network.

Therefore, it is important that you constantly monitor your instance and find if you are reaching the storage limits.

Managed Instance provides a system view in master database called sys.server_resource_stats that contains information about the CPU usage, reserved and used storage that enables you to monitor usage in the real-time:
<pre>select top 1 avg_cpu_percent,
storage_space_used_mb / reserved_storage_mb
from master.sys.server_resource_stats
order by start_time desc</pre>
This view contains snapshots of 5-min usage on the Managed Instance in last two weeks, so you just take the most recent row and see CPU/storage usage. You can periodically run the query on Manage Instance and take some action if the percentages get high.
<h2>Sending alerts using db_mail</h2>
As an alternative, you can enable db_mail feature and send the email alerts directly from Managed Instance once you are close to resource limits. If you haven't configured emails on Managed Instance <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/08/31/sending-emails-in-azure-sql-managed-instance/">take a look at this post</a>.

The following script will send you an email if CPU usage is above 95% and storage usage is above 90%:
<pre>declare @cpu_perc float, @storage_perc float;
declare @instance nvarchar(200) = @@SERVERNAME;

select top 1 @cpu_perc = avg_cpu_percent,
@storage_perc = storage_space_used_mb / reserved_storage_mb
from master.sys.server_resource_stats order by start_time desc

if(@cpu_perc &gt; .95 or @storage_perc &gt; .9)
begin

declare @msg nvarchar(max) = CONCAT('You are reaching the compute/storage limits of your instance ', @@SERVERNAME, ':
Storage ', @storage_perc, '%
CPU usage:', @cpu_perc, '%
Consider upgrading the instance.');
exec msdb.dbo.sp_notify_operator 
@profile_name = N'AzureManagedInstance_dbmail_profile', 
@name = N'DevOps team', 
@subject = N'Azure SQL Instance - Storage limit alert', 
@body = @msg;
end
</pre>
CPU limit might not be critical and you might find the average CPU usage in last few hours. However, if you are reaching the storage limit you should take some actions faster and add more storage or free-up some space on your instance.

You can easily automate this query and copy/paste it into SQL Agent job that will run every 15 minutes and send the email if you are reaching the limit.
<a href="https://msdnshared.blob.core.windows.net/media/2019/03/monitor-sql-agent.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/monitor-sql-agent-1024x909.png" alt="" width="879" height="780" class="alignnone size-large wp-image-8475" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Analyzing wait statistics on Managed Instance</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/analyzing-wait-statistics-on-managed-instance</link>
      <pubDate>Tue, 05 Mar 2019 06:56:13 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8425</guid>
      <description><![CDATA[Wait statistics are information that might help you understand why the query duration is long and...]]></description>
      <content:encoded><![CDATA[Wait statistics are information that might help you understand why the query duration is long and identify the queries that are waiting for something in database engine. In this post, I will show to you how to identify why the workload is waiting and what are the queries that are waiting on some resources.

<!--more-->

Azure SQL Managed Instance enables you to find why the queries are waiting for some resources using the following views:
<ul>
 	<li>sys.dm_os_wait_stats that returns instance level wait statistics</li>
 	<li>sys.query_store_wait_stats that returns query-plan wait statistics per database.</li>
</ul>
These information can be found using DMO/Query store. However, to make the the analysis easier, I'm using free/open-source <a href="https://github.com/JocaPC/qpi">QPI library</a>. This library is not a prerequisite, but it makes analysis easier because it has pre-defined views that join all necessary Query Store views to fetch the information. Since this library is open-source you can copy-paste the query examples from the views and use them even without installing the whole library.

In addition, it takes the snapshots of the wait stats and enables you to see wait statistics in the past.

To install QPI library go to <a href="https://github.com/JocaPC/qpi#installation">the installation section</a> and download the SQL script for your version of SQL Server (it supports Azure SQL/SQL Server 2016+ because it depends on Query Store views).
<h2>Analyze wait statistics</h2>
First thing that you need to do is to take a snapshot of the wait statistics or at least reset them because <span style="font-family: Consolas, Monaco, monospace">sys.dm_os_wait_stats</span> collects wait statistics since the instance start or the last time you reset the stats. In QPI, you can use the following procedure to reset the wait statistics:
<pre>exec qpi.snapshot_wait_stats</pre>
This procedure will reset wait statistics on your instance and the Managed Instance will start collecting new wait statistics.

While your workload is running, you can read the wait statistics values from the qpi.wait_stats view:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/wait-stats.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/wait-stats-1024x228.png" alt="" width="879" height="196" class="alignnone size-large wp-image-8435" /></a>

This view returns wait statistics and also their categories. Here you can see that the main wait statistic on my instance is INSTANCE_LOG_RATE_GOVERNOR categorized as Log Rate Governor. If you don't know what is some wait statistic, you can follow the URL in info column and go to sqlskills site to find more details.

The category is important because if you want to find the queries affected by the wait type you need to use category in Query Store and not actual wait type name. Wait statistics in query store are not recorded per wait type.
<blockquote>There is a mapping logic between wait types and wait categories that is documented on SQL Server documentation and these rules are added in this library. This is important because this is the only link between global wait statistics and query store wait statistics.</blockquote>
If you want to see top queries affected by this wait category, you can use <strong>qpi.db_query_wait_stats</strong> view and filter the wait statistics per category:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/query-wait-stats.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/query-wait-stats-1024x232.png" alt="" width="879" height="199" class="alignnone size-large wp-image-8445" /></a>

In this case you can see that I'm hitting log rate limit on the Managed Instance and that this is probably caused by rebuild index statement. If you have multiple databases, you need to run this query in each of them because Query Store is configured per database.

These views can enable you to easily troubleshoot the issues on your instance and drill down to the queries that might cause problems or the queries that are affected by some wait type.

QPI is open-source library that is not official part of SQL Server/Azure SQL Db scripts. If you find any issue in this library you can file a bug or submit the PR with the change.]]></content:encoded>
    </item>
    <item>
      <title>Reduced recompilations for workloads using temporary tables across multiple scopes</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/reduced-recompilations-for-workloads-using-temporary-tables-across-multiple-scopes</link>
      <pubDate>Mon, 04 Mar 2019 13:55:21 GMT</pubDate>
      <dc:creator><![CDATA[Joseph Sack]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8375</guid>
      <description><![CDATA[SQL Server 2019 introduces several performance optimizations which will improve performance with...]]></description>
      <content:encoded><![CDATA[SQL Server 2019 introduces several performance optimizations which will improve performance with <a target="_blank" href="https://docs.microsoft.com/en-us/sql/relational-databases/performance/intelligent-query-processing?view=sql-server-2017" rel="noopener">minimal changes required to your application code</a>.   In this blog post we’ll discuss one such improvement available in CTP 2.3: <strong>reduced recompilations for workloads using temporary tables in multiple scopes</strong>.

In order to understand this improvement, we’ll first go over the current behavior in SQL Server 2017 and prior. When referencing a temporary table with a DML statement (SELECT, INSERT, UPDATE, DELETE), if the temporary table was created by an outer scope batch, we will recompile the DML statement <em>each time it is executed</em>.

The following example illustrates this behavior:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/1_RR.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/1_RR.png" alt="" width="457" height="252" class="alignnone size-full wp-image-8385" /></a>

In the outer procedure we:
<ol>
 	<li>Create a temporary table</li>
 	<li>Call a stored procedure</li>
</ol>
The inner stored procedure definition is as follows:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/2_RR1.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/2_RR1.png" alt="" width="689" height="229" class="alignnone size-full wp-image-8405" /></a>

For the inner stored procedure, we have two DML statements that reference the temporary table created in the outer scope where we:
<ol start="3">
 	<li>Insert a row into the temporary table.</li>
 	<li>Return the row from the temporary table.</li>
</ol>
We created the temporary table in a different scope from the DML statements, and for the existing implementation (pre-SQL Server 2019), we don’t “trust” that this temporary table schema hasn’t been materially changed and so we recompile the associated DML statements <em>each time they are executed</em>. This additional recompilation activity increases CPU utilization and can decrease overall workload performance and throughput.

Starting with SQL Server 2019 CTP 2.3, we will perform additional lightweight checks to avoid unnecessary recompilations:
<ul>
 	<li>We will check if the outer-scope module used for creating the temporary table at compile time is the same one used for consecutive executions.</li>
 	<li>We will keep track of any data definition language (DDL) changes made at initial compilation and compare them with DDL operations for consecutive executions.</li>
</ul>
The end result is a reduction in unwarranted recompilations and associated CPU-overhead.

The below figure shows test results from 16 concurrent threads each executing the “OutProc” stored procedure 1,000 times (in a loop). The Y-axis represents the number of occurrences, with the blue line representing <strong>Batch Requests/sec</strong> and the green line representing <strong>SQL Re-Compilations/sec</strong>:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/3_RR.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/3_RR.png" alt="" width="1019" height="635" class="alignnone wp-image-8415" /></a>

When the feature was enabled, for this example we saw:
<ul>
 	<li>Improved throughput, as represented by Batch Requests/sec (blue line, second hump).</li>
 	<li>Shorter overall workload duration.</li>
 	<li>Reduced recompilations, as represented by SQL Re-Compilations/sec (green line) showing only a small increase at the beginning of the second test.</li>
</ul>
This feature is enabled by default in SQL Server 2019 CTP 2.3 under all database compatibility levels. As of this writing, this feature is also enabled in Azure SQL Database under database compatibility level 150, although it will soon be applied across all database compatibility levels (matching the behavior of SQL Server 2019).

If you have feedback on this feature or other query processing features, please email us at <a href="mailto:IntelligentQP@microsoft.com">IntelligentQP@microsoft.com</a>.]]></content:encoded>
    </item>
    <item>
      <title>Measuring file io performance on Managed Instance using QPI</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/measuring-file-io-performance-on-managed-instance-qpi</link>
      <pubDate>Mon, 04 Mar 2019 10:39:37 GMT</pubDate>
      <dc:creator><![CDATA[Jovan Popovic (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8345</guid>
      <description><![CDATA[Checking file performance and comparing performance characteristics between SQL Server database...]]></description>
      <content:encoded><![CDATA[Checking file performance and comparing performance characteristics between SQL Server database engines in Azure cloud and your on-premises environment might be tricky and require some better knowledge of DM objects. In this post, you will see how to use one open-source library that can help you to analyze and compare file performance.

<!--more-->

SQL Server and Azure SQL Managed Instance enable you to measure IO characteristics of your database files using sys.dm_io_virtual_file_stats DM object. However, you must be aware that this DM returns cumulative values that should be sampled and you would need to calculate the differences in IO stats between two period of times. If you need to extract information from this DM object, you should read the following articles:
<ul>
 	<li>Paul Randal<span> </span><a href="https://www.sqlskills.com/blogs/paul/how-to-examine-io-subsystem-latencies-from-within-sql-server/" rel="nofollow">How to examine IO subsystem latencies</a></li>
 	<li>Erin Stellato<span> </span><a href="https://sqlperformance.com/2013/10/t-sql-queries/io-latency" rel="nofollow">What Virtual Filestats Do, and Do Not, Tell You About I/O Latency</a>.</li>
</ul>
If you don't have prepared scripts you can use the following open-source library: https://github.com/JocaPC/qpi where you have some useful prepared views that can help you analyze your file latency. This is a helper T-SQL library that enables you to:
<ol>
 	<li>Take the snapshots of your sys.dm_io_virtual_file_stats</li>
 	<li>Calculates the values such as IO throughput, latency, etc. Calculations are same/similar as in Paul &amp; Erin scripts.</li>
 	<li>Enables you to go back in past and examine the latency of the previous snapshot - this is a small additional functionality compared to Paul &amp; Erin scripts.</li>
</ol>
<h2>Prerequisite - install QPI</h2>
As a first step you should install QPI library on your Managed Instance/SQL Server. Go to <a href="https://github.com/JocaPC/qpi#installation">installation section</a> and choose the version of QPI library depending on your SQL Server version. Only versions higher than SQL Server 2016 are supported because it uses SQL Server 2016 temporal tables to store the history of IO statistics.
<blockquote>This is plain T-SQL script that you can review to make sure that there is nothing dangerous inside.</blockquote>
This script will add a set of views/procedures in <strong>QPI</strong> schema in your database.
<h2>Analyzing io statistics</h2>
First you need to take a snapshot of the current values in sys.dm_io_virtual_file_stats DM object using the following command:
<pre>EXEC qpi.snapshot_file_stats;</pre>
This is the baseline for IO statistics and you can get the cumulative/average values until this point. Now you need to keep your workload running until the moment where you want to measure IO performance using the following view:
<pre>SELECT * FROM qpi.file_stats;</pre>
In the results of this view you can find information about the size of each file, IOPS, throughput, latency, etc.

You can also get the IO statistics in the current database:
<pre>SELECT * FROM qpi.db_file_stats;
</pre>
The results are shown on the following image:

<a href="https://msdnshared.blob.core.windows.net/media/2019/03/db_file_stats.png"><img src="https://msdnshared.blob.core.windows.net/media/2019/03/db_file_stats-1024x163.png" alt="" width="879" height="140" class="alignnone size-large wp-image-8355" /></a>

Most of the columns are self-explanatory, but there is difference in the following two:
<ul>
 	<li><strong>read_latency_ms/write_latency_ms</strong> represent average latency to complete request end-to-end.</li>
 	<li><strong>read_io_latency_ms/write_io_latency_ms</strong> represent average latency to complete request in IO subsystem. Ideally it should be same as read_latency_ms/write_latency_ms. If there is a difference, then SQL Server Database Engine cannot catch-up procession IO requests or introduces some IO throttling.</li>
</ul>
You can also get the file statistics from some point in time in the past (make sure that you had done snapshot before this pint in time):
<pre>SELECT * FROM qpi.file_stats_as_of( &lt;some date&gt; );</pre>
If you are comparing IO performance results on Managed Instance and your on-prem or Azure SQL VM (IaaS) try to compare the results from this query in order to get the consistent results and fair comparison.
<h2>Conclusion</h2>
QPI is a set of useful scripts that can help you to more easily analyze performance of your database files.

QPI is open-source library and if you find any issue in the functions feel free to post the bug submit or pull request with a fix.]]></content:encoded>
    </item>
    <item>
      <title>We are moving!</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/we-are-moving</link>
      <pubDate>Mon, 04 Mar 2019 10:21:47 GMT</pubDate>
      <dc:creator><![CDATA[Pam Lahoud]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8365</guid>
      <description><![CDATA[This blog is in the process of being migrated to one of the new consolidated SQL Server and Azure...]]></description>
      <content:encoded><![CDATA[This blog is in the process of being migrated to one of the new consolidated <a href="https://techcommunity.microsoft.com/t5/SQL-Server/ct-p/SQL-Server">SQL Server</a> and <a href="https://techcommunity.microsoft.com/t5/Azure-SQL-Database/bg-p/Azure-SQL-Database">Azure SQL Database</a> blogs on the <a href="https://techcommunity.microsoft.com/">Microsoft TechCommunity</a> website. Once the migration is complete, we will post the new URL along with instructions for how to navigate the new blog and update your RSS feeds. Until then, feel free to keep reading here, but keep in mind that any comments that are added may not make it over to the new blog. You will be able to re-post them there once we are live. Stay tuned and see you on the new site soon!]]></content:encoded>
    </item>
    <item>
      <title>Azure Stream Analytics now supports Azure SQL Database as reference data input</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/azure-stream-analytics-now-supports-azure-sql-database-as-reference-data-input</link>
      <pubDate>Mon, 04 Feb 2019 16:35:13 GMT</pubDate>
      <dc:creator><![CDATA[Ajay.MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlserverstorageengine/?p=8335</guid>
      <description><![CDATA[Reference data is a dataset that is static or slow changing in nature which you can correlate with...]]></description>
      <content:encoded><![CDATA[<p>Reference data is a dataset that is static or slow changing in nature which you can correlate with real-time data streams to augment the data. Azure Stream Analytics leverages versioning of reference data to augment streaming data by the reference data that was valid at the time the event was generated. One of the most popular customer requests is to be able to use Azure SQL Database as reference data input for Stream Analytics.</p><p>We are excited to announce that this capability is now available in public preview.</p><p>For more information and to get started with using Azure SQL Database as your reference data set for Azure Stream Analytics, see this <a href="https://azure.microsoft.com/en-us/blog/azure-stream-analytics-now-supports-azure-sql-database-as-reference-data-input/" target="_blank">announcement</a>.</p>]]></content:encoded>
    </item>
  </channel>
</rss>