<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arvind Toorpu</title>
    <description>The latest articles on DEV Community by Arvind Toorpu (@arvind_toorpu).</description>
    <link>https://dev.to/arvind_toorpu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png</url>
      <title>DEV Community: Arvind Toorpu</title>
      <link>https://dev.to/arvind_toorpu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arvind_toorpu"/>
    <language>en</language>
    <item>
      <title>Your AG Secondaries Aren't Load Balancing Because You Skipped One Step</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Mon, 14 Sep 2026 13:46:00 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/your-ag-secondaries-arent-load-balancing-because-you-skipped-one-step-3bda</link>
      <guid>https://dev.to/arvind_toorpu/your-ag-secondaries-arent-load-balancing-because-you-skipped-one-step-3bda</guid>
      <description>&lt;p&gt;A client paged me at 6am because their reporting dashboards were timing out. Nothing was down. The primary replica in their Always On AG was just getting hammered by every single read query in the environment, while two perfectly healthy secondary replicas sat there doing nothing but redo. They had "configured" read-scale months earlier: &lt;code&gt;ALLOW_CONNECTIONS = READ_ONLY&lt;/code&gt; was set on both secondaries, the app connection string had &lt;code&gt;ApplicationIntent=ReadOnly&lt;/code&gt;, and none of it mattered because nobody had built the read-only routing list on the primary. Connections with read intent were falling through to the primary because that's what happens by default when a routing list doesn't exist.&lt;/p&gt;

&lt;p&gt;That's the whole point of this post. Making a secondary readable and getting traffic to actually route to it are two different configuration steps, and skipping the second one is the single most common mistake I see in AG read-scale setups.&lt;/p&gt;

&lt;h2&gt;
  
  
  What read-only routing actually is
&lt;/h2&gt;

&lt;p&gt;Read-only routing is a primary-replica-side redirect. A client connects to the listener (or, in a clusterless read-scale AG, to a replica directly) with &lt;code&gt;ApplicationIntent=ReadOnly&lt;/code&gt; in the connection string. If the instance it lands on is the primary, SQL Server checks whether a read-only routing list exists for that primary. If one does, it transparently redirects the connection to whichever secondary the list points to. No list, no redirect, the connection just runs read-write on the primary like normal.&lt;/p&gt;

&lt;p&gt;Since SQL Server 2017 you don't even need a Windows Server Failover Cluster to get this: a read-scale availability group can exist without a cluster at all, purely to fan out read workload across replicas (&lt;a href="https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/read-scale-availability-groups?view=sql-server-ver17" rel="noopener noreferrer"&gt;Microsoft Learn&lt;/a&gt;). Be clear with yourself and your team about what that buys you, though: a cluster-less read-scale AG has no automatic failover. There's no cluster manager watching health and flipping the primary role for you. If you need that, you're building a normal Always On AG with WSFC (or Pacemaker on Linux) and layering read-only routing on top of it, which is the far more common production pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring it end to end
&lt;/h2&gt;

&lt;p&gt;Here's the sequence that actually works, on a standard Windows-clustered AG with two readable secondaries.&lt;/p&gt;

&lt;p&gt;First, mark each secondary as readable and give it a routing URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;AVAILABILITY&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AG1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="n"&gt;REPLICA&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE02'&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SECONDARY_ROLE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ALLOW_CONNECTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;READ_ONLY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;READ_ONLY_ROUTING_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'TCP://SQLNODE02.corp.local:1433'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;AVAILABILITY&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AG1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="n"&gt;REPLICA&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE03'&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SECONDARY_ROLE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ALLOW_CONNECTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;READ_ONLY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;READ_ONLY_ROUTING_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'TCP://SQLNODE03.corp.local:1433'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the step people actually remember. Here's the one they don't: the routing list has to be defined on whichever replica is currently the primary, because that's the instance doing the redirecting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;AVAILABILITY&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AG1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="n"&gt;REPLICA&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE01'&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PRIMARY_ROLE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;READ_ONLY_ROUTING_LIST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE02'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE03'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'SQLNODE01'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That nested-parentheses syntax, &lt;code&gt;(('SQLNODE02','SQLNODE03'), 'SQLNODE01')&lt;/code&gt;, is load-balanced round-robin routing across SQLNODE02 and SQLNODE03, with SQLNODE01 (the primary) as the fallback if both are unavailable. That's a SQL Server 2016+ feature; only one level of nesting is supported (&lt;a href="https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/configure-read-only-routing-for-an-availability-group-sql-server?view=sql-server-ver17" rel="noopener noreferrer"&gt;Microsoft Learn&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Because any node can become primary during a failover, you need to repeat that &lt;code&gt;PRIMARY_ROLE&lt;/code&gt; routing list definition on every replica, each one listing itself last as the fallback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;AVAILABILITY&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AG1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="n"&gt;REPLICA&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE02'&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PRIMARY_ROLE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;READ_ONLY_ROUTING_LIST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE03'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'SQLNODE02'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;AVAILABILITY&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AG1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="n"&gt;REPLICA&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE03'&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PRIMARY_ROLE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;READ_ONLY_ROUTING_LIST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'SQLNODE02'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'SQLNODE03'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the client side, the connection string needs the intent flag and, if the listener spans subnets, multi-subnet failover:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;tcp:AG1-Listener,1433;Database=Sales;Application Intent=ReadOnly;MultiSubnetFailover=True;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ad hoc testing from SSMS or &lt;code&gt;sqlcmd&lt;/code&gt;, you can confirm which node you actually landed on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;&lt;span class="n"&gt;SERVERNAME&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;routed_to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_hadr_is_primary_replica&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sales'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;is_primary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to check what's actually registered on the primary before you blame the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;ag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ag_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replica_server_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_only_routing_url&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;availability_read_only_routing_lists&lt;/span&gt; &lt;span class="n"&gt;rl&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;availability_replicas&lt;/span&gt; &lt;span class="n"&gt;ar&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replica_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replica_id&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;availability_groups&lt;/span&gt; &lt;span class="n"&gt;ag&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That query would have caught my client's problem in about ten seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this requires care
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The primary needs a routing URL too.&lt;/strong&gt; If the routing list ever falls back to the primary (or a client connects to the primary directly with read intent and no list exists yet), and the primary itself has no &lt;code&gt;READ_ONLY_ROUTING_URL&lt;/code&gt;, routing fails outright rather than silently running on the primary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load-balanced routing is round-robin per new connection, not per query.&lt;/strong&gt; It's not smart about replica lag or current load. If SQLNODE03 is 40 seconds behind on redo because of a big index rebuild, round-robin will happily send a client there and that client will see stale data with no warning. If your reporting workload is lag-sensitive, monitor &lt;code&gt;sys.dm_hadr_database_replica_states.secondary_lag_seconds&lt;/code&gt; and either alert on it or take that replica out of the routing list temporarily during heavy write windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Readable secondaries are not free connections.&lt;/strong&gt; They're separate SQL Server instances and, outside a passive failover-only configuration, they need to be licensed like any other active SQL Server. This trips up teams who treat "we already pay for AG" as covering read-scale for free. Check your licensing terms, don't assume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Availability Groups on Standard Edition don't support readable secondaries at all.&lt;/strong&gt; If you're on Standard Edition, you get one AG, one database, no read access to the secondary, full stop. Read-scale in the way this article describes needs Enterprise Edition (or SQL Server 2017+ read-scale-without-a-cluster, which has its own edition rules, worth double-checking against your specific version).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application Intent is case-sensitive in spelling but the driver matters more than you'd think.&lt;/strong&gt; Some older ODBC/JDBC driver versions silently drop or mishandle &lt;code&gt;ApplicationIntent&lt;/code&gt;. If routing isn't happening and your T-SQL config checks out clean, check the actual driver version and connection string the app is sending, not just what you think you configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  My take
&lt;/h2&gt;

&lt;p&gt;Read-only routing is one of those Always On features that looks like a checkbox in the wizard and is actually two independent, un-obviously-linked configuration objects: the secondary's readability plus URL, and the primary's routing list. SSMS's Add Replica wizard doesn't force you through the second one clearly, and I've seen more environments get half-configured than fully configured. If you're rolling this out, script both steps together, verify with the DMV query above as part of your deployment, and don't trust the dashboard alone to tell you traffic is actually landing where you think it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/configure-read-only-routing-for-an-availability-group-sql-server?view=sql-server-ver17" rel="noopener noreferrer"&gt;Configure read-only routing for an availability group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/read-scale-availability-groups?view=sql-server-ver17" rel="noopener noreferrer"&gt;Use read-scale with Always On availability groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-availability-read-only-routing-lists-transact-sql?view=sql-server-ver17" rel="noopener noreferrer"&gt;sys.availability_read_only_routing_lists (Transact-SQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-configure-rs?view=sql-server-ver16" rel="noopener noreferrer"&gt;Configure a Read-Scale Availability Group (SQL Server on Linux)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sqlserver</category>
      <category>database</category>
      <category>ha</category>
      <category>tsql</category>
    </item>
    <item>
      <title>S3 Express One Zone Got Cheaper and Gained Inventory Support. Time to Reconsider It</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Thu, 10 Sep 2026 15:52:00 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/s3-express-one-zone-got-cheaper-and-gained-inventory-support-time-to-reconsider-it-3pi5</link>
      <guid>https://dev.to/arvind_toorpu/s3-express-one-zone-got-cheaper-and-gained-inventory-support-time-to-reconsider-it-3pi5</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F38kzgchjvisrb31i9k3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F38kzgchjvisrb31i9k3n.png" alt="S3 Express One Zone Got Cheaper and Gained Inventory Support" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;S3 Express One Zone launched back in 2023 with a pretty specific pitch: single-digit millisecond latency, up to 10x faster than S3 Standard, for workloads that actually need it. The catch was cost and a missing feature set that made it hard to run in production the same way you'd run Standard. Two 2026 updates change that calculus: a big price cut, and S3 Inventory support finally landing in April.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pitch, quickly
&lt;/h2&gt;

&lt;p&gt;S3 Express One Zone stores data in a single Availability Zone (hence "One Zone") in a directory bucket, not the usual S3 bucket structure. In exchange for giving up multi-AZ redundancy, you get consistent low-latency access, request costs up to 80% lower than Standard, and throughput that's genuinely built for latency-sensitive access patterns: ML training data loading, interactive analytics, key-value caching for AI search.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api create-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-express-bucket--use1-az4--x-s3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--create-bucket-configuration&lt;/span&gt; &lt;span class="s1"&gt;'{"Location":{"Type":"AvailabilityZone","Name":"use1-az4"},"Bucket":{"Type":"Directory","DataRedundancy":"SingleAvailabilityZone"}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the bucket naming convention: directory buckets need that &lt;code&gt;--use1-az4--x-s3&lt;/code&gt; suffix pattern, they're not just a regular bucket with a flag flipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  The price cut
&lt;/h2&gt;

&lt;p&gt;AWS announced price reductions of up to 85% for S3 Express One Zone. That's a meaningful shift in the cost-benefit calculation. At the original pricing, the latency win had to be worth a real premium to justify using it over Standard plus a caching layer. At the new pricing, that math looks a lot more favorable for a wider range of workloads, not just the most latency-obsessed ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  S3 Inventory support (April 2026)
&lt;/h2&gt;

&lt;p&gt;This is the operational gap that made Express One Zone hard to run seriously before. S3 Inventory generates scheduled reports (daily or weekly) listing every object in a bucket or prefix along with metadata like size, encryption status, and last modified time. Without it, if you wanted to know what was actually sitting in a directory bucket, you were stuck listing objects programmatically, which doesn't scale well for buckets with millions of objects.&lt;/p&gt;

&lt;p&gt;Now you can set it up the same way you would for a Standard bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-inventory-configuration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-express-bucket--use1-az4--x-s3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--id&lt;/span&gt; daily-inventory &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--inventory-configuration&lt;/span&gt; &lt;span class="s1"&gt;'{
    "Destination": {
      "S3BucketDestination": {
        "Bucket": "arn:aws:s3:::my-inventory-reports",
        "Format": "Parquet"
      }
    },
    "IsEnabled": true,
    "Id": "daily-inventory",
    "IncludedObjectVersions": "Current",
    "Schedule": {"Frequency": "Daily"}
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That output landing as Parquet in a regular bucket means you can query it directly with Athena, which is a much saner way to audit a large directory bucket than paging through ListObjectsV2 results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it actually fits
&lt;/h2&gt;

&lt;p&gt;The realistic use cases haven't changed, they've just gotten cheaper to justify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ML training data staging.&lt;/strong&gt; Loading training batches with consistent low latency, especially paired with SageMaker's optimized data channels, which now integrate natively with directory buckets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive analytics scratch space.&lt;/strong&gt; Query engines that need to read and write intermediate results fast, where S3 Standard's latency profile becomes the bottleneck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI search key-value caching.&lt;/strong&gt; Storing embeddings or lookup data where request latency directly affects user-facing response time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it doesn't fit
&lt;/h2&gt;

&lt;p&gt;Single-AZ means single-AZ. If the AZ your directory bucket lives in has an outage, your data is unavailable until that AZ recovers, full stop. This isn't a subtle tradeoff, it's the whole design point of the product, and it means Express One Zone is a poor fit for anything that's your durable source of truth. Treat it as a performance tier for data that either has a durable copy elsewhere (like the original training dataset in S3 Standard) or is inherently ephemeral (like intermediate compute results you can regenerate).&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it without commitment
&lt;/h2&gt;

&lt;p&gt;Availability has been expanding steadily, Frankfurt joined the list of supported Regions in July 2026, bringing the total to eight. If your workload's home Region wasn't covered before, it's worth checking again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api list-directory-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; eu-central-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A quick cost sanity check before you migrate anything
&lt;/h2&gt;

&lt;p&gt;Before moving a workload over, it's worth running a small side-by-side test rather than trusting the headline "up to 85% cheaper" number blindly, since your actual savings depend heavily on your specific request pattern (lots of small GETs versus fewer large ones behaves very differently on request-based pricing). Stand up a directory bucket, mirror a day's worth of real traffic against it alongside your existing Standard bucket, and compare the actual bill delta rather than the marketing number. It's a couple hours of setup that turns "AWS says it's cheaper" into "here's what it actually costs for our workload."&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;If you evaluated S3 Express One Zone in 2023 or 2024 and decided the cost didn't justify the latency win for your workload, it's genuinely worth re-running that math now. Between the price cut and Inventory support closing the biggest operational gap, this moved from "niche latency tool" to "reasonable default for a wider set of performance-sensitive workloads" in about a year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/aws/up-to-85-price-reductions-for-amazon-s3-express-one-zone/" rel="noopener noreferrer"&gt;Announcing up to 85% price reductions for Amazon S3 Express One Zone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/04/s3-express-one-zone-supports-s3-inventory/" rel="noopener noreferrer"&gt;Amazon S3 Express One Zone now supports S3 Inventory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-bucket-high-performance.html" rel="noopener noreferrer"&gt;High performance workloads with S3 directory buckets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>cloud</category>
      <category>data</category>
    </item>
    <item>
      <title>SnapStart Basically Kills Lambda Cold Starts for Java, Python, and .NET. Here's How to Actually Use It</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Fri, 04 Sep 2026 12:49:00 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/snapstart-basically-kills-lambda-cold-starts-for-java-python-and-net-heres-how-to-actually-use-36g9</link>
      <guid>https://dev.to/arvind_toorpu/snapstart-basically-kills-lambda-cold-starts-for-java-python-and-net-heres-how-to-actually-use-36g9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdg7mj3vislz7dxcdk7oq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdg7mj3vislz7dxcdk7oq.png" alt="SnapStart Basically Kills Lambda Cold Starts for Java" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cold starts are the one Lambda complaint that never really goes away, especially if you're running Java or a heavier Python stack. SnapStart is AWS's answer, and it's now generally available for Java, Python 3.12+, and .NET 8+. If you haven't touched it yet, this is worth an afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SnapStart actually does
&lt;/h2&gt;

&lt;p&gt;Instead of initializing your function's runtime, dependencies, and execution environment from a cold start every time, SnapStart takes a snapshot of a fully initialized execution environment (memory and disk state, post-init) and caches it. When a new instance is needed, Lambda resumes from that snapshot instead of running your init code from scratch.&lt;/p&gt;

&lt;p&gt;The practical result: init-phase latency drops by 70 to 90 percent for supported runtimes, according to AWS's own numbers. For a Java function with a heavy Spring context to boot, that's the difference between a multi-second cold start and something that barely registers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling it
&lt;/h2&gt;

&lt;p&gt;For a supported runtime, it's a one-line change in your function configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws lambda update-function-configuration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--function-name&lt;/span&gt; my-java-function &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snap-start&lt;/span&gt; &lt;span class="nv"&gt;ApplyOn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PublishedVersions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;ApplyOn=PublishedVersions&lt;/code&gt; part. SnapStart only applies to published versions of your function, not &lt;code&gt;$LATEST&lt;/code&gt;. That trips people up the first time, since testing against &lt;code&gt;$LATEST&lt;/code&gt; in the console won't show any SnapStart benefit at all.&lt;/p&gt;

&lt;p&gt;Via SAM or CDK, it looks like this (CDK, Python):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;aws_cdk&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;aws_lambda&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;lambda_&lt;/span&gt;

&lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MyFunction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lambda_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JAVA_21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;com.example.Handler::handleRequest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lambda_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_asset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;build/function.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;snap_start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lambda_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SnapStartConf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ON_PUBLISHED_VERSIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The gotcha nobody warns you about: uniqueness
&lt;/h2&gt;

&lt;p&gt;Snapshots capture your execution environment's state, including anything you initialized before the handler runs, like a random seed, a cached secret, or a database connection. If your init code generates something that's supposed to be unique per execution environment (a UUID used as an instance identifier, for example) and you generate it once outside the handler, every resumed snapshot will have the exact same value, because they're all resuming from the identical frozen state.&lt;/p&gt;

&lt;p&gt;AWS's guidance here is specific: anything that needs to be unique per invocation or per environment needs to be regenerated inside the handler, or you need to use the Lambda runtime hooks (&lt;code&gt;beforeCheckpoint&lt;/code&gt; and &lt;code&gt;afterRestore&lt;/code&gt; for Java) to refresh things like connections and credentials on resume rather than assuming init-time state stays valid forever.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java: refreshing a connection on restore using runtime hooks&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.CoreLifecycleHooks&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;dbConnection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CoreLifecycleHooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerBeforeCheckpoint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;beforeCheckpoint&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;CoreLifecycleHooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerAfterRestore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;afterRestore&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;afterRestore&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// re-establish anything that shouldn't be shared across resumed snapshots&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dbConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createFreshConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Java 25 made this better
&lt;/h2&gt;

&lt;p&gt;Java 25 on Lambda changed how tiered compilation interacts with SnapStart and Provisioned Concurrency. Previously, SnapStart would stop compilation optimization at tier C1. Starting with Java 25, that cap is gone, so functions get the benefit of full JIT optimization even when running from a SnapStart snapshot, instead of being stuck at a less-optimized compilation tier indefinitely.&lt;/p&gt;

&lt;p&gt;If you're on an older Java version specifically because you assumed SnapStart's compilation ceiling was a permanent limitation, it's worth re-checking against Java 25.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's NOT supported
&lt;/h2&gt;

&lt;p&gt;Worth knowing before you go looking for it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Container image functions&lt;/strong&gt; don't support SnapStart, only zip-based deployments on supported managed runtimes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js and Ruby runtimes&lt;/strong&gt; aren't supported as of this writing; only Java 11+, Python 3.12+, and .NET 8+.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OS-only (provided.al2/al2023) runtimes&lt;/strong&gt; aren't supported either.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pairing it with Graviton
&lt;/h2&gt;

&lt;p&gt;SnapStart cuts init latency. Graviton (arm64) instances cut execution cost and generally improve throughput for CPU-bound workloads. They're independent levers, and stacking both together is a reasonable default for any new Java or Python Lambda function where cold start and cost both matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# SAM template snippet&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;MyFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;java21&lt;/span&gt;
      &lt;span class="na"&gt;Architectures&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
      &lt;span class="na"&gt;SnapStart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ApplyOn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublishedVersions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Should you turn this on everywhere
&lt;/h2&gt;

&lt;p&gt;For Java functions specifically, yes, almost by default, given how much init-phase latency Java pays compared to something like Node. For Python and .NET, it's still worth it if you're seeing meaningful cold start impact on user-facing latency, but the win is smaller since those runtimes generally cold-start faster to begin with.&lt;/p&gt;

&lt;p&gt;The one thing I'd actually test before flipping it on for a production function: run your function through a few resume cycles and check for any state that quietly stayed frozen from the snapshot when you expected it to be fresh. That's the failure mode that doesn't show up in a quick smoke test, only in production traffic days or weeks later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html" rel="noopener noreferrer"&gt;Improving startup performance with Lambda SnapStart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/aws/aws-lambda-snapstart-for-python-and-net-functions-is-now-generally-available/" rel="noopener noreferrer"&gt;AWS Lambda SnapStart for Python and .NET functions is now generally available&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/aws-lambda-now-supports-java-25/" rel="noopener noreferrer"&gt;AWS Lambda now supports Java 25&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>lambda</category>
      <category>performance</category>
    </item>
    <item>
      <title>Mastering Columnstore Indexes in SQL Server: New Features and Performance Enhancements in</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Wed, 11 Jun 2025 15:29:28 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-1c31</link>
      <guid>https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-1c31</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6" class="crayons-story__hidden-navigation-link"&gt;Mastering Columnstore Indexes in SQL Server: New Features and Performance Enhancements in 2022&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/arvind_toorpu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" alt="arvind_toorpu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/arvind_toorpu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Arvind Toorpu
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Arvind Toorpu
                
              
              &lt;div id="story-author-preview-content-2242976" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/arvind_toorpu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Arvind Toorpu&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 18 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6" id="article-link-2242976"&gt;
          Mastering Columnstore Indexes in SQL Server: New Features and Performance Enhancements in 2022
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>sql</category>
      <category>sqlserver</category>
      <category>performance</category>
      <category>database</category>
    </item>
    <item>
      <title>Make the most of the SQL Server Max DOP parameter to enhance your query run time by embracing parallelism!</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Wed, 11 Jun 2025 15:22:33 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/make-the-most-of-the-sql-server-max-dop-parameter-to-enhance-your-query-run-time-by-embracing-2a0l</link>
      <guid>https://dev.to/arvind_toorpu/make-the-most-of-the-sql-server-max-dop-parameter-to-enhance-your-query-run-time-by-embracing-2a0l</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg" class="crayons-story__hidden-navigation-link"&gt;Optimizing SQL Server Index Rebuilds with MAXDOP&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/arvind_toorpu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" alt="arvind_toorpu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/arvind_toorpu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Arvind Toorpu
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Arvind Toorpu
                
              
              &lt;div id="story-author-preview-content-2327874" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/arvind_toorpu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Arvind Toorpu&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 7 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg" id="article-link-2327874"&gt;
          Optimizing SQL Server Index Rebuilds with MAXDOP
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sqlserver"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sqlserver&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/database"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;database&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/dba"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;dba&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>aws</category>
      <category>sqlserver</category>
      <category>database</category>
      <category>dba</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Fri, 23 May 2025 18:43:24 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/-2nj6</link>
      <guid>https://dev.to/arvind_toorpu/-2nj6</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g" class="crayons-story__hidden-navigation-link"&gt;Troubleshooting tempdb Growth: Identifying Idle Sessions Holding Temporary Resources in SQL Server&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/arvind_toorpu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" alt="arvind_toorpu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/arvind_toorpu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Arvind Toorpu
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Arvind Toorpu
                
              
              &lt;div id="story-author-preview-content-2250579" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/arvind_toorpu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1933970%2Ff4ee48ef-ebd9-4c2a-94c1-845642bf3996.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Arvind Toorpu&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 25 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g" id="article-link-2250579"&gt;
          Troubleshooting tempdb Growth: Identifying Idle Sessions Holding Temporary Resources in SQL Server
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/database"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;database&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sqlserver"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sqlserver&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/dba"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;dba&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>aws</category>
      <category>database</category>
      <category>sqlserver</category>
      <category>dba</category>
    </item>
    <item>
      <title>Optimizing SQL Server Index Rebuilds with MAXDOP</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Wed, 07 May 2025 11:30:00 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg</link>
      <guid>https://dev.to/arvind_toorpu/optimizing-sql-server-index-rebuilds-with-maxdop-4flg</guid>
      <description>&lt;h1&gt;
  
  
  Optimizing SQL Server Index Rebuilds with MAXDOP: A Practical Guide
&lt;/h1&gt;

&lt;p&gt;Keeping your SQL Server databases running at peak performance requires regular index maintenance. One critical but often overlooked aspect is how &lt;strong&gt;parallelism&lt;/strong&gt;, controlled through the &lt;code&gt;MAXDOP&lt;/code&gt; setting, can significantly impact the speed and efficiency of index rebuilds. In this guide, we'll walk through how you can optimize your SQL Server index maintenance by properly configuring &lt;code&gt;MAXDOP&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yihphhlrn0nezr74qwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yihphhlrn0nezr74qwk.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Index Maintenance Matters
&lt;/h2&gt;

&lt;p&gt;Index fragmentation is an inevitable side effect of everyday database operations like inserts, updates, and deletes. Over time, fragmented indexes can lead to slower queries and increased I/O, affecting the overall performance of your applications.&lt;/p&gt;

&lt;p&gt;Performing regular index maintenance — through &lt;strong&gt;rebuilds&lt;/strong&gt; or &lt;strong&gt;reorganizations&lt;/strong&gt; — is essential to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce query response times&lt;/li&gt;
&lt;li&gt;Improve system throughput&lt;/li&gt;
&lt;li&gt;Maintain efficient storage usage&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/sql/relational-databases/indexes/reorganize-and-rebuild-indexes?view=sql-server-ver16" rel="noopener noreferrer"&gt;Learn more about index maintenance best practices from SQL Server Docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Harnessing the Power of Parallelism with MAXDOP
&lt;/h2&gt;

&lt;p&gt;SQL Server can utilize multiple processors when performing index operations. The &lt;strong&gt;Maximum Degree of Parallelism (MAXDOP)&lt;/strong&gt; setting controls how many CPU cores SQL Server can use for these operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting MAXDOP During Index Rebuilds
&lt;/h3&gt;

&lt;p&gt;By default, index operations follow the instance-level &lt;code&gt;MAXDOP&lt;/code&gt; setting. However, you can explicitly override this for specific rebuilds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IX_Sales_OrderDate&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Sales&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command instructs SQL Server to use 4 processor cores for rebuilding the index, regardless of the server’s default &lt;code&gt;MAXDOP&lt;/code&gt; setting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reference: &lt;a href="https://www.mssqltips.com/sqlservertip/3100/reduce-time-for-sql-server-index-rebuilds-and-update-statistics/" rel="noopener noreferrer"&gt;Reduce Time for SQL Server Index Rebuilds and Update Statistics&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Benchmark Results: How MAXDOP Affects Rebuild Times
&lt;/h2&gt;

&lt;p&gt;To illustrate the real-world impact, I ran tests on a large table containing 15 million rows (~60GB) using different &lt;code&gt;MAXDOP&lt;/code&gt; values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Setup:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQL Server&lt;/strong&gt;: 2022 Enterprise Edition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cores&lt;/strong&gt;: 16 logical processors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: 128GB RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt;: NVMe SSD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table&lt;/strong&gt;: SalesTransactions (60GB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index&lt;/strong&gt;: IX_SalesTransactions_TransactionDate (Non-clustered)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance Results:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MAXDOP Setting&lt;/th&gt;
&lt;th&gt;Rebuild Duration (seconds)&lt;/th&gt;
&lt;th&gt;CPU Utilization (%)&lt;/th&gt;
&lt;th&gt;Memory Usage (GB)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;420&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;2.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;240&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;4.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;135&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;7.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;12.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;td&gt;95&lt;/td&gt;
&lt;td&gt;12.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;72&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;12.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Significant performance improvements were observed up to &lt;code&gt;MAXDOP = 8&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Beyond 8, performance gains were marginal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This aligns with Microsoft's guidance to limit &lt;code&gt;MAXDOP&lt;/code&gt; to &lt;strong&gt;8 or fewer&lt;/strong&gt; for most workloads.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical MAXDOP Configuration Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: 24x7 Production System
&lt;/h3&gt;

&lt;p&gt;In environments with continuous user activity, balance is crucial.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IX_CustomerTransactions_TransactionDate&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Sales&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;CustomerTransactions&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ONLINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Moderate parallelism ensures faster rebuilds without heavily impacting user workloads.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ONLINE = ON&lt;/code&gt; allows queries to continue during the rebuild.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenario 2: Dedicated Maintenance Window
&lt;/h3&gt;

&lt;p&gt;If you have a maintenance window with minimal load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Sales&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;OrderDetails&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Higher parallelism maximizes rebuild speed.&lt;/li&gt;
&lt;li&gt;Ideal when users are offline or during planned downtimes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenario 3: Resource-Constrained Systems
&lt;/h3&gt;

&lt;p&gt;On systems with limited CPU or concurrent heavy usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IX_Inventory_ProductID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REORGANIZE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PK_Inventory_Products&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prefer &lt;strong&gt;reorganization&lt;/strong&gt; over &lt;strong&gt;rebuild&lt;/strong&gt; when possible.&lt;/li&gt;
&lt;li&gt;Limit &lt;code&gt;MAXDOP&lt;/code&gt; for minimal disruption.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Reorganize operations are &lt;strong&gt;single-threaded&lt;/strong&gt; by design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Best Practices for Setting MAXDOP
&lt;/h2&gt;

&lt;p&gt;When fine-tuning &lt;code&gt;MAXDOP&lt;/code&gt; for index operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with &lt;code&gt;MAXDOP = 0.5 × (physical cores)&lt;/code&gt; (up to 8).&lt;/li&gt;
&lt;li&gt;Monitor system waits and resource usage during rebuilds.&lt;/li&gt;
&lt;li&gt;For OLTP systems, restrict &lt;code&gt;MAXDOP&lt;/code&gt; to 4 or fewer during peak hours.&lt;/li&gt;
&lt;li&gt;Evaluate your storage subsystem — parallelism increases I/O!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example configuration for a 16-core server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IX_FactInternetSales_OrderDate&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;FactInternetSales&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SORT_IN_TEMPDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SORT_IN_TEMPDB = ON&lt;/code&gt; offloads sorting operations, reducing contention in user databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Important Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Edition&lt;/strong&gt; is required for parallel index rebuilds. Standard Edition operations remain single-threaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reorganize operations&lt;/strong&gt; do not use multiple threads.&lt;/li&gt;
&lt;li&gt;Online rebuilds with &lt;code&gt;ALLOW_PAGE_LOCKS = OFF&lt;/code&gt; and &lt;code&gt;MAXDOP &amp;gt; 1&lt;/code&gt; can lead to increased fragmentation.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;MAXDOP&lt;/code&gt; exceeds available CPUs, SQL Server uses the maximum available automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Validate MAXDOP Settings
&lt;/h2&gt;

&lt;p&gt;You can confirm your MAXDOP usage by capturing execution plans:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EVENT&lt;/span&gt; &lt;span class="k"&gt;SESSION&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CapturePlans&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="n"&gt;EVENT&lt;/span&gt; &lt;span class="n"&gt;sqlserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_post_execution_showplan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ACTION&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sqlserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql_text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="n"&gt;TARGET&lt;/span&gt; &lt;span class="n"&gt;package0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;event_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="s1"&gt;'C:&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;emp&lt;/span&gt;&lt;span class="se"&gt;\C&lt;/span&gt;&lt;span class="s1"&gt;apturePlans.xel'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAX_MEMORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt; &lt;span class="n"&gt;KB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EVENT_RETENTION_MODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ALLOW_SINGLE_EVENT_LOSS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;MAX_DISPATCH_LATENCY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="n"&gt;SECONDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;STARTUP_STATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;OFF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;EVENT&lt;/span&gt; &lt;span class="k"&gt;SESSION&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CapturePlans&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="k"&gt;STATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;START&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Execute your index rebuild&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IX_Sales_CustomerID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Sales&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;REBUILD&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAXDOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;EVENT&lt;/span&gt; &lt;span class="k"&gt;SESSION&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CapturePlans&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="k"&gt;STATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;STOP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analyze the captured event file to review the degree of parallelism utilized.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Tuning &lt;code&gt;MAXDOP&lt;/code&gt; for index rebuilds is a powerful way to optimize SQL Server maintenance without sacrificing user experience. With careful configuration based on your environment's needs, you can dramatically reduce maintenance windows and keep your databases performing at their best.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>sqlserver</category>
      <category>database</category>
      <category>dba</category>
    </item>
    <item>
      <title>Troubleshooting tempdb Growth: Identifying Idle Sessions Holding Temporary Resources in SQL Server</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Fri, 25 Apr 2025 17:00:40 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g</link>
      <guid>https://dev.to/arvind_toorpu/troubleshooting-tempdb-growth-identifying-idle-sessions-holding-temporary-resources-in-sql-server-3j2g</guid>
      <description>&lt;p&gt;To find out how much &lt;strong&gt;tempdb&lt;/strong&gt; disk space is occupied by each session that is connected and is idle in a SQL Server database, you can use the following query. This query leverages Dynamic Management Views (DMVs) like &lt;code&gt;sys.dm_db_session_space_usage&lt;/code&gt; and &lt;code&gt;sys.dm_exec_sessions&lt;/code&gt; to identify idle sessions and their &lt;strong&gt;tempdb&lt;/strong&gt; usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query to Find &lt;strong&gt;tempdb&lt;/strong&gt; Disk Space Usage by Idle Sessions:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;program_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_alloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_dealloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_dealloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_alloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_dealloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_dealloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_dealloc_page_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_net_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_dealloc_page_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_net_mb&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_db_session_space_usage&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; 
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt; &lt;span class="n"&gt;es&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sleeping'&lt;/span&gt; &lt;span class="c1"&gt;-- Filter for idle sessions&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- Filter for sessions using tempdb&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;user_objects_net_mb&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;internal_objects_net_mb&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation of the Query:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sys.dm_db_session_space_usage&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracks &lt;strong&gt;tempdb&lt;/strong&gt; space usage for each session.&lt;/li&gt;
&lt;li&gt;Columns like &lt;code&gt;user_objects_alloc_page_count&lt;/code&gt; and &lt;code&gt;internal_objects_alloc_page_count&lt;/code&gt; show the number of 8 KB pages allocated for user objects (e.g., temporary tables) and internal objects (e.g., worktables).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sys.dm_exec_sessions&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides session-level information, such as &lt;code&gt;session_id&lt;/code&gt;, &lt;code&gt;login_name&lt;/code&gt;, &lt;code&gt;host_name&lt;/code&gt;, &lt;code&gt;program_name&lt;/code&gt;, and &lt;code&gt;status&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;status&lt;/code&gt; column is used to filter for idle sessions (&lt;code&gt;status = 'sleeping'&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calculations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiply page counts by &lt;code&gt;8 / 1024.0&lt;/code&gt; to convert pages to megabytes (MB).&lt;/li&gt;
&lt;li&gt;Calculate the &lt;strong&gt;net&lt;/strong&gt; space usage by subtracting deallocated pages from allocated pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Filters&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;es.status = 'sleeping'&lt;/code&gt;: Filters for sessions that are idle (not actively running queries).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;su.user_objects_alloc_page_count &amp;gt; 0 OR su.internal_objects_alloc_page_count &amp;gt; 0&lt;/code&gt;: Ensures only sessions using &lt;strong&gt;tempdb&lt;/strong&gt; are included.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;user_objects_net_mb&lt;/code&gt;&lt;/strong&gt;: Net space used by user objects (e.g., temporary tables) in MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal_objects_net_mb&lt;/code&gt;&lt;/strong&gt;: Net space used by internal objects (e.g., worktables) in MB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example Output:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;session_id&lt;/th&gt;
&lt;th&gt;login_name&lt;/th&gt;
&lt;th&gt;host_name&lt;/th&gt;
&lt;th&gt;program_name&lt;/th&gt;
&lt;th&gt;status&lt;/th&gt;
&lt;th&gt;user_objects_alloc_mb&lt;/th&gt;
&lt;th&gt;user_objects_dealloc_mb&lt;/th&gt;
&lt;th&gt;internal_objects_alloc_mb&lt;/th&gt;
&lt;th&gt;internal_objects_dealloc_mb&lt;/th&gt;
&lt;th&gt;user_objects_net_mb&lt;/th&gt;
&lt;th&gt;internal_objects_net_mb&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;sa&lt;/td&gt;
&lt;td&gt;SQLHost01&lt;/td&gt;
&lt;td&gt;SQLServerManagement&lt;/td&gt;
&lt;td&gt;sleeping&lt;/td&gt;
&lt;td&gt;50.25&lt;/td&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;td&gt;20.50&lt;/td&gt;
&lt;td&gt;5.00&lt;/td&gt;
&lt;td&gt;40.25&lt;/td&gt;
&lt;td&gt;15.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;app_user&lt;/td&gt;
&lt;td&gt;AppServer01&lt;/td&gt;
&lt;td&gt;MyApp.exe&lt;/td&gt;
&lt;td&gt;sleeping&lt;/td&gt;
&lt;td&gt;30.00&lt;/td&gt;
&lt;td&gt;30.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Key Notes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Idle sessions (&lt;code&gt;status = 'sleeping'&lt;/code&gt;) may still hold &lt;strong&gt;tempdb&lt;/strong&gt; resources if they have not explicitly dropped temporary objects or if their scope has not ended.&lt;/li&gt;
&lt;li&gt;If you notice high &lt;strong&gt;tempdb&lt;/strong&gt; usage by idle sessions, investigate whether temporary objects are being properly cleaned up or if long-running transactions are holding resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This query is a great way to monitor and troubleshoot &lt;strong&gt;tempdb&lt;/strong&gt; usage, especially in environments with high concurrency or large temporary object usage.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>database</category>
      <category>sqlserver</category>
      <category>dba</category>
    </item>
    <item>
      <title>Auditing SQL Server Database User Activity in AWS RDS: A Step-by-Step Guide</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Wed, 12 Mar 2025 14:47:23 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/auditing-sql-server-database-user-activity-in-aws-rds-a-step-by-step-guide-1jb8</link>
      <guid>https://dev.to/arvind_toorpu/auditing-sql-server-database-user-activity-in-aws-rds-a-step-by-step-guide-1jb8</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Auditing SQL Server Database User Activity in AWS RDS: A Step-by-Step Guide&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Auditing user activity in SQL Server on AWS RDS involves leveraging AWS-native tools combined with SQL Server's built-in features. in this article I provide a detailed guide for setting up and managing auditing:&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Enable SQL Server Audit in AWS RDS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SQL Server Audit is supported on RDS and can track user activity. Here's how to enable and configure it:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1.1 Configure an Audit Parameter Group&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the &lt;strong&gt;AWS Management Console&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;RDS&lt;/strong&gt; &amp;gt; &lt;strong&gt;Parameter Groups&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new parameter group for your SQL Server instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;Parameter group family&lt;/strong&gt; matching your SQL Server version.&lt;/li&gt;
&lt;li&gt;Set the name, e.g., &lt;code&gt;sqlserver-audit-group&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the parameter group:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for the parameter &lt;code&gt;rds.sqlserver_audit&lt;/code&gt; and set it to &lt;strong&gt;1&lt;/strong&gt; (enabled).&lt;/li&gt;
&lt;li&gt;Save the changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Associate the parameter group with your RDS instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;RDS Instances&lt;/strong&gt; and select your SQL Server instance.&lt;/li&gt;
&lt;li&gt;Modify the instance and change the parameter group to the new one.&lt;/li&gt;
&lt;li&gt;Apply changes (you may need to reboot the instance for changes to take effect).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Set Up SQL Server Audit&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once the audit feature is enabled, configure it at the database level.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2.1 Create an Audit Object&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This defines where the audit logs will be stored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="n"&gt;AUDIT&lt;/span&gt; &lt;span class="n"&gt;AuditToFile&lt;/span&gt;
&lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;FILE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILEPATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'D:&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s1"&gt;dsdbdata&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s1"&gt;QLAudit&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;);
GO
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;2.2 Create an Audit Specification&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Define the events to capture in the audit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="n"&gt;AUDIT&lt;/span&gt; &lt;span class="n"&gt;SPECIFICATION&lt;/span&gt; &lt;span class="n"&gt;AuditUserLogins&lt;/span&gt;
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="n"&gt;AUDIT&lt;/span&gt; &lt;span class="n"&gt;AuditToFile&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUCCESSFUL_LOGIN_GROUP&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FAILED_LOGIN_GROUP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;2.3 Enable the Audit and Specification&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="n"&gt;AUDIT&lt;/span&gt; &lt;span class="n"&gt;AuditToFile&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;STATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt; &lt;span class="n"&gt;AUDIT&lt;/span&gt; &lt;span class="n"&gt;SPECIFICATION&lt;/span&gt; &lt;span class="n"&gt;AuditUserLogins&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;STATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Access and Review Audit Logs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Audit logs for RDS SQL Server are stored in the default directory (&lt;code&gt;D:\rdsdbdata\SQLAudit\&lt;/code&gt;) and can be accessed via the &lt;strong&gt;AWS Management Console&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;RDS&lt;/strong&gt; &amp;gt; &lt;strong&gt;Your Instance&lt;/strong&gt; &amp;gt; &lt;strong&gt;Logs and Events&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Locate logs with the prefix &lt;code&gt;SQL_AUDIT_LOG&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Download the logs to review them locally.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alternatively, query the logs directly using the SQL Server function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn_get_audit_file&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'D:&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s1"&gt;dsdbdata&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s1"&gt;QLAudit&lt;/span&gt;&lt;span class="se"&gt;\*&lt;/span&gt;&lt;span class="s1"&gt;.sqlaudit'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Use CloudWatch for Enhanced Monitoring&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Integrate SQL Server activity logs with AWS CloudWatch for centralized monitoring and alerting.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4.1 Enable Enhanced Monitoring&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;strong&gt;RDS Console&lt;/strong&gt;, go to your SQL Server instance.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Enhanced Monitoring&lt;/strong&gt; and set the monitoring interval.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4.2 Stream Audit Logs to CloudWatch&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;RDS&lt;/strong&gt; &amp;gt; &lt;strong&gt;Log Exports&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;SQL Server Audit Logs&lt;/strong&gt; for export to CloudWatch.&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;CloudWatch&lt;/strong&gt;, create a log group and associate the logs with it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4.3 Set Up CloudWatch Alerts&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Create a metric filter for specific events (e.g., failed logins).&lt;/li&gt;
&lt;li&gt;Configure an alarm to notify you when thresholds are breached.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5: Query User Activity with Dynamic Management Views (DMVs)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Leverage SQL Server DMVs to query real-time user activity.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;5.1 Track Active Sessions&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;login_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;program_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;database_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;is_user_process&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;5.2 Review Recent Logins&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;login_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;login_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_net_address&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_connections&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_connections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;5.3 Monitor Query Activity&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;query_text&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_requests&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="n"&gt;APPLY&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sql_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Step 6: Automate Alerts and Notifications&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;6.1 Use Event Notifications&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Set up event notifications for specific actions, such as failed logins or schema changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EVENT&lt;/span&gt; &lt;span class="n"&gt;NOTIFICATION&lt;/span&gt; &lt;span class="n"&gt;FailedLoginAlert&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SERVER&lt;/span&gt;
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="n"&gt;FAILED_LOGIN&lt;/span&gt;
&lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;SERVICE&lt;/span&gt; &lt;span class="s1"&gt;'MyService'&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;6.2 Configure Alerts in AWS RDS&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Use the AWS &lt;strong&gt;EventBridge&lt;/strong&gt; to trigger actions (e.g., email notifications) for specific RDS events.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 7: Best Practices for RDS SQL Server Auditing&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Minimize Audit Overhead:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Audit only the necessary events to reduce performance impact.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Audit Logs:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Restrict access to audit logs in RDS and CloudWatch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regularly Review Logs:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Analyze audit logs periodically for anomalies or suspicious activity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate Responses:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS automation tools to handle critical events like repeated failed logins.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable Encryption:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ensure audit logs and database communications are encrypted.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Auditing user activity in SQL Server on AWS RDS combines SQL Server’s robust auditing features with AWS's monitoring and alerting capabilities. By following this step-by-step guide, you can ensure a secure, compliant, and well-monitored SQL Server environment. Regular audits help mitigate risks, detect anomalies, and maintain database integrity, which is essential for modern, data-driven organizations. &lt;/p&gt;

</description>
      <category>sqlserver</category>
      <category>security</category>
      <category>aws</category>
      <category>database</category>
    </item>
    <item>
      <title>Oracle Database Migration from Windows to Linux Using RMAN Transportable Tablespace</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Tue, 04 Mar 2025 16:26:55 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/oracle-database-migration-from-windows-to-linux-using-rman-transportable-tablespace-4o5a</link>
      <guid>https://dev.to/arvind_toorpu/oracle-database-migration-from-windows-to-linux-using-rman-transportable-tablespace-4o5a</guid>
      <description>&lt;h2&gt;
  
  
  Oracle Database Migration from Windows to Linux Using RMAN Transportable Tablespace
&lt;/h2&gt;

&lt;p&gt;Migrating an Oracle database between different operating systems can often feel daunting. However, with the right tools and steps, this process can be more manageable than it seems. In this article, we will walk through migrating an Oracle database from Windows to Linux using the RMAN Transportable Tablespace feature - one of the most efficient methods for such a task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oracle Database installed on both Windows and Linux servers. Network connectivity between the two servers. Sufficient disk space on both servers. Basic understanding of RMAN and Oracle database administration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-by-Step Migration&lt;/strong&gt;&lt;br&gt;
Prepare the Source Database (Windows)&lt;/p&gt;

&lt;p&gt;First, we need to ensure the source database is in READ ONLY mode. This step is crucial to prevent any changes during the migration process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; ALTER DATABASE OPEN READ ONLY;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identify the Tablespaces to be Transported&lt;/p&gt;

&lt;p&gt;Identify the tablespaces that you want to transport. For this example, we will transport the sales_data tablespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; SELECT tablespace_name FROM dba_tablespaces;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generate the Transportable Tablespace Set&lt;/strong&gt;&lt;br&gt;
Use RMAN to create the transportable tablespace set, including metadata files and datafiles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rman target / 

RMAN&amp;gt; TRANSPORT TABLESPACE sales_data  
TABLESPACE DESTINATION '/tmp/transport_tbs'  
EXPORT LOG '/tmp/transport_tbs/tts_export.log';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates the datafiles and a transportable tablespace set in the specified destination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transfer Files to the Destination Server (Linux)&lt;/strong&gt;&lt;br&gt;
Using a secure copy tool like scp, transfer the files to the target Linux server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scp /tmp/transport_tbs/* oracle@linux_server:/tmp/transport_tbs/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prepare the Target Database (Linux)&lt;/strong&gt;&lt;br&gt;
Create the necessary directories and ensure the target database is up and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
SQL&amp;gt; CREATE TABLESPACE sales_data DATAFILE '/u01/app/oracle/oradata/sales_data01.dbf' SIZE 100M;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Import Metadata&lt;/strong&gt;&lt;br&gt;
Use Data Pump to import the metadata into the target database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impdp system/password DIRECTORY=dpump_dir1 DUMPFILE=sales_data.dmp 
TRANSPORT_DATAFILES='/u01/app/oracle/oradata/sales_data01.dbf';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Make the Tablespaces Read/Write&lt;/strong&gt;&lt;br&gt;
Once the import is complete, make the tablespace read/write.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; ALTER TABLESPACE sales_data READ WRITE;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Verify the Migration&lt;/strong&gt;&lt;br&gt;
Confirm the tablespace and data have been transported correctly by querying the objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; SELECT * FROM dba_tablespaces WHERE tablespace_name='SALES_DATA'; 

SQL&amp;gt; SELECT * FROM sales.orders WHERE ROWNUM  EXEC DBMS_TTS.TRANSPORT_SET_CHECK('sales_data', TRUE);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Convert the Endianness (if required)&lt;/strong&gt;&lt;br&gt;
Use RMAN to convert the data files if the source and target platforms have different endian formats.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    RMAN&amp;gt; CONVERT DATAFILE '/tmp/transport_tbs/sales_data01.dbf'
    TO PLATFORM="Linux x86 64-bit"
    FROM PLATFORM="Windows NT (32-bit)"
    DB_FILE_NAME_CONVERT ('/tmp/transport_tbs', '/u01/app/oracle/oradata');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Import Metadata as detailed above&lt;/strong&gt;&lt;br&gt;
Following these steps, you can efficiently migrate your Oracle database from Windows to Linux using the RMAN Transportable Tablespace feature, ensuring minimal downtime and data integrity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
Database migration might seem a strenuous process, but with Oracle RMAN Transportable Tablespace, it becomes structured and manageable. Adapting this guide to your specific scenarios will help in achieving this transition smoothly. If you encounter any issues, Oracle's documentation and community forums are excellent resources for troubleshooting and additional guidance.&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>database</category>
      <category>migration</category>
      <category>cloud</category>
    </item>
    <item>
      <title>SQL Server tempdb Deep Dive: Monitoring Usage and Reclaiming Space with Shrink Operations</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Wed, 26 Feb 2025 19:40:30 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/sql-server-tempdb-deep-dive-monitoring-usage-and-reclaiming-space-with-shrink-operations-54jj</link>
      <guid>https://dev.to/arvind_toorpu/sql-server-tempdb-deep-dive-monitoring-usage-and-reclaiming-space-with-shrink-operations-54jj</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Query 1: Identify tempdb Usage by Sessions That Could Be Released by Disconnecting&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This query identifies sessions that are holding &lt;strong&gt;tempdb&lt;/strong&gt; resources and could release them if disconnected. It focuses on sessions that are idle (&lt;code&gt;sleeping&lt;/code&gt;) and still have allocated &lt;strong&gt;tempdb&lt;/strong&gt; space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;program_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_alloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_dealloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_dealloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_alloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_dealloc_page_count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_dealloc_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_dealloc_page_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;user_objects_net_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_dealloc_page_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;internal_objects_net_mb&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_db_session_space_usage&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; 
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_exec_sessions&lt;/span&gt; &lt;span class="n"&gt;es&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;es&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sleeping'&lt;/span&gt; &lt;span class="c1"&gt;-- Filter for idle sessions&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;su&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;internal_objects_alloc_page_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- Filter for sessions using tempdb&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;user_objects_net_mb&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;internal_objects_net_mb&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Key Outputs:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;user_objects_net_mb&lt;/code&gt;&lt;/strong&gt;: Net space used by user objects (e.g., temporary tables) in MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal_objects_net_mb&lt;/code&gt;&lt;/strong&gt;: Net space used by internal objects (e.g., worktables) in MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;session_id&lt;/code&gt;&lt;/strong&gt;: The ID of the session holding the resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;status&lt;/code&gt;&lt;/strong&gt;: Indicates if the session is idle (&lt;code&gt;sleeping&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Action:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If these sessions are no longer needed, you can disconnect them using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;KILL&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Query 2: Estimate tempdb Disk Space That Can Be Reclaimed by Running SHRINKFILE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This query estimates the amount of &lt;strong&gt;tempdb&lt;/strong&gt; space that can be reclaimed by running &lt;code&gt;SHRINKFILE&lt;/code&gt;. It uses the &lt;code&gt;sys.dm_db_file_space_usage&lt;/code&gt; DMV to identify unused space in &lt;strong&gt;tempdb&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;current_size_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;FILEPROPERTY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SpaceUsed'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;used_space_mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;FILEPROPERTY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SpaceUsed'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;free_space_mb&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;master_files&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;database_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DB_ID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tempdb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- 0 = Data file, 1 = Log file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Key Outputs:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;current_size_mb&lt;/code&gt;&lt;/strong&gt;: Current size of the &lt;strong&gt;tempdb&lt;/strong&gt; data file in MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;used_space_mb&lt;/code&gt;&lt;/strong&gt;: Space actively used in the &lt;strong&gt;tempdb&lt;/strong&gt; data file in MB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;free_space_mb&lt;/code&gt;&lt;/strong&gt;: Free space that can potentially be reclaimed by shrinking the &lt;strong&gt;tempdb&lt;/strong&gt; data file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Action:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If there is significant free space, you can reclaim it by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;tempdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;DBCC&lt;/span&gt; &lt;span class="n"&gt;SHRINKFILE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tempdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_size_in_mb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;-- Replace 'tempdev' with the logical name of your tempdb data file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Important Notes:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Disconnecting Sessions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disconnecting sessions should be done cautiously, as it may disrupt active processes or users.&lt;/li&gt;
&lt;li&gt;Ensure the sessions are truly idle and no longer needed before killing them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shrinking tempdb:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shrinking &lt;strong&gt;tempdb&lt;/strong&gt; is generally not recommended unless absolutely necessary, as it can lead to fragmentation and performance overhead.&lt;/li&gt;
&lt;li&gt;If &lt;strong&gt;tempdb&lt;/strong&gt; grows frequently, consider increasing its initial size to avoid frequent auto-growth events.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitoring:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regularly monitor &lt;strong&gt;tempdb&lt;/strong&gt; usage using the provided queries to proactively manage resources and avoid contention.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Mastering Columnstore Indexes in SQL Server: New Features and Performance Enhancements in 2022</title>
      <dc:creator>Arvind Toorpu</dc:creator>
      <pubDate>Tue, 18 Feb 2025 01:10:12 +0000</pubDate>
      <link>https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6</link>
      <guid>https://dev.to/arvind_toorpu/mastering-columnstore-indexes-in-sql-server-new-features-and-performance-enhancements-in-2022-58d6</guid>
      <description>&lt;h3&gt;
  
  
  Mastering Columnstore Indexes in SQL Server: New Features and Performance Enhancements in 2022
&lt;/h3&gt;

&lt;p&gt;Columnstore indexes in SQL Server have become a cornerstone for improving performance in analytical workloads, particularly for large datasets. With the latest enhancements in SQL Server 2022, these indexes are more powerful, versatile, and capable of boosting performance across diverse scenarios. This article explores these enhancements with practical examples to help you understand and implement them effectively.  &lt;/p&gt;




&lt;h3&gt;
  
  
  1. Ordered Columnstore Indexes
&lt;/h3&gt;

&lt;p&gt;SQL Server 2022 introduces the ability to create ordered columnstore indexes. Sorting the data while building a columnstore index improves compression efficiency and enables faster queries for range-based filters.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Suppose we have a sales table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;SalesID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;SalesDate&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;SalesAmount&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create an ordered columnstore index by &lt;code&gt;SalesDate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;CLUSTERED&lt;/span&gt; &lt;span class="n"&gt;COLUMNSTORE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;CCI_SalesData&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Before Ordering: Querying a range of dates, e.g., sales data for a specific year, would involve scanning unsorted row groups.
&lt;/li&gt;
&lt;li&gt;After Ordering: The query benefits from improved compression and faster access since data is sorted by &lt;code&gt;SalesDate&lt;/code&gt;. This is particularly useful for time-series queries such as &lt;code&gt;WHERE SalesDate BETWEEN '2025-01-01' AND '2025-12-31'&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Batch Mode on Rowstore
&lt;/h3&gt;

&lt;p&gt;Batch mode execution, traditionally available only for columnstore indexes, is now extended to rowstore tables in SQL Server 2022. This feature allows analytical workloads on rowstore tables to benefit from batch processing, improving query performance.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Consider a &lt;code&gt;Products&lt;/code&gt; table stored as a rowstore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ProductID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Category&lt;/span&gt; &lt;span class="n"&gt;NVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query using batch mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;AvgPrice&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Products&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;
&lt;span class="k"&gt;OPTION&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;HINT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ENABLE_BATCH_MODE'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Without Batch Mode: The query processes rows one by one, which is slower for analytical tasks.
&lt;/li&gt;
&lt;li&gt;With Batch Mode: Data is processed in batches, leading to significant performance gains by minimizing CPU and memory usage.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Enhanced Support in Always On Availability Groups
&lt;/h3&gt;

&lt;p&gt;Columnstore indexes now support querying on readable secondary replicas in Always On Availability Groups. This enhancement allows organizations to offload analytical workloads to secondary replicas.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Assume an Always On configuration with a primary and a secondary replica. On the secondary replica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalSales&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Primary Replica: Reserved for transactional operations.
&lt;/li&gt;
&lt;li&gt;Secondary Replica: Processes read-intensive queries involving columnstore indexes, reducing the workload on the primary replica while maintaining high availability.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Improved Diagnostic Capabilities
&lt;/h3&gt;

&lt;p&gt;The new DMV &lt;code&gt;sys.dm_db_column_store_row_group_physical_stats&lt;/code&gt; provides detailed insights into the health and efficiency of row groups in columnstore indexes.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;To inspect a columnstore index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_db_column_store_row_group_physical_stats&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;object_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OBJECT_ID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SalesData'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Insights Gained: The DMV reveals metrics such as the number of rows per row group, compression status, and whether segments are being pushed to disk or remain in memory.
&lt;/li&gt;
&lt;li&gt;Use Case: Identifying poorly compressed or fragmented row groups to decide whether to rebuild or reorganize the columnstore index.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. Batch Mode for Single-Threaded Queries
&lt;/h3&gt;

&lt;p&gt;SQL Server now supports batch mode processing even for single-threaded queries, which was previously limited to multi-threaded scenarios.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Query with a single-threaded operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalSales&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Before: Single-threaded queries executed row by row, consuming more resources.
&lt;/li&gt;
&lt;li&gt;After: Batch mode optimizes the execution by processing data in chunks, resulting in faster queries even without parallelism.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  6. Batch Mode for the SORT Operator
&lt;/h3&gt;

&lt;p&gt;The SORT operator in SQL Server now supports batch mode execution when working with columnstore indexes.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Suppose you want to rank sales records by &lt;code&gt;SalesAmount&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;SalesID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;RANK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;SalesAmount&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Without Batch Mode: Sorting large datasets row by row is resource-intensive.
&lt;/li&gt;
&lt;li&gt;With Batch Mode: Sorting is performed in batches, reducing the CPU and memory overhead while improving the overall efficiency.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Performance Comparison Using Benchmark
&lt;/h3&gt;

&lt;p&gt;Let’s quantify the impact of columnstore indexes using a benchmark experiment with a table containing 20 million rows.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Setup
&lt;/h4&gt;

&lt;p&gt;Create the table and populate it with 20 million rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;SalesID&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;SalesDate&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;SalesAmount&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert 20 million rows&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TOP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20000000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;SalesID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ABS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CHECKSUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NEWID&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;RAND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CHECKSUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NEWID&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;SalesAmount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spt_values&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spt_values&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query Performance Without Columnstore Index
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalSales&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Execution Time: ~50 seconds
&lt;/li&gt;
&lt;li&gt;Rows Processed: 20 million
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Add Columnstore Index
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;CLUSTERED&lt;/span&gt; &lt;span class="n"&gt;COLUMNSTORE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;CCI_SalesData&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query Performance With Columnstore Index
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalSales&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SalesData&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;SalesDate&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Execution Time: ~2 seconds
&lt;/li&gt;
&lt;li&gt;Rows Processed: ~1 million (compressed row groups)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The latest advancements in columnstore indexes—such as ordered indexes, batch mode on rowstore, and extended diagnostic capabilities—have made SQL Server 2022 a powerful platform for handling analytical workloads. By leveraging these features, organizations can achieve remarkable performance improvements, especially for large datasets, making columnstore indexes an indispensable tool in modern database management.  &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
