{"id":6730,"date":"2026-03-18T10:00:33","date_gmt":"2026-03-18T17:00:33","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=6730"},"modified":"2026-03-18T10:01:28","modified_gmt":"2026-03-18T17:01:28","slug":"diskann-vector-index-improvements","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/diskann-vector-index-improvements\/","title":{"rendered":"DiskANN Vector Index Improvements"},"content":{"rendered":"<p>Remember when we announced the <strong>Public Preview of DiskANN vector indexes<\/strong> back in <a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/public-preview-of-vector-indexing-in-azure-sql-db-azure-sql-mi-and-sql-database-in-microsoft-fabric\/\">November<\/a> and mentioned that once you created the index, your table became read\u2011only? Yeah\u2026 about that&#8230; \ud83d\ude05 We shipped early because the demand for Vector search in SQL was overwhelming. We knew the constraints weren\u2019t ideal, but we also knew the fastest way to get this into your hands was to <strong>iterate in public<\/strong>.<\/p>\n<p>You gave us feedback. Lots of it! And today, we\u2019re excited to say: those major preview limitations are gone. We are happy to announce that the <strong>DiskANN Vector Index public preview<\/strong> just received a <strong>major upgrade<\/strong>, removing the initial constraints and unlocking high\u2011performance vector search at scale without sacrificing day\u2011to\u2011day operations.<\/p>\n<h2><strong>What&#8217;s New<\/strong><\/h2>\n<p>Pretty much all the major limitations are gone:<\/p>\n<ul>\n<li><strong>Full DML support<\/strong> \u2013 Tables are no longer read\u2011only after index creation<\/li>\n<li><strong>Iterative filtering<\/strong> \u2013 Filters are applied <em>during<\/em> vector search, not after (no more manual TOP_N hints needed)<\/li>\n<li><strong>Smarter optimizer<\/strong> \u2013 Automatically chooses between DiskANN and exact KNN<\/li>\n<li><strong>Improved quantization<\/strong> \u2013 Faster builds and better search quality<\/li>\n<\/ul>\n<h2><strong>Availability<\/strong><\/h2>\n<p>As announced today at <a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/announcing-sqlcon-2026-better-together-with-fabcon\/4466701\"><strong>SQLCon<\/strong><\/a>, these improvements are rolling out across Azure SQL Database and SQL database in Microsoft Fabric. Deployments are happening worldwide, and availability may vary by region. Check the <a href=\"link\">documentation<\/a> for availability in your region. Run this quick check to see if your region has the new version:<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">-- Check if the new DMV exists\r\nSELECT OBJECT_ID('sys.dm_db_vector_indexes') AS new_dmv_available;<\/code><\/pre>\n<p>If this returns NULL, your region hasn&#8217;t received the deployment yet. Check back in a few days! If instead it returns a number, you&#8217;re good to go!<\/p>\n<h2><strong>Creating Vector Indexes (No Changes!)<\/strong><\/h2>\n<p>Good news: <strong>the syntax hasn\u2019t changed<\/strong>. Any vector index you create now automatically uses the latest version<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">CREATE VECTOR INDEX vec_idx \r\n    ON dbo.wikipedia_articles (title_vector)\r\n    WITH (METRIC = 'cosine', TYPE = 'diskann');<\/code><\/pre>\n<p>What <strong><em>has<\/em><\/strong> changed is what happens under the hood: index creation is now <strong>significantly faster<\/strong>, thanks to Optimized graph construction, improved parallelization, and a new quantization approach. Build time still depends on your data size and service tier, but for large datasets especially millions of rows you should notice a big difference. This comes at the cost of slightly larger index files on disk, a tradeoff that works well for most deployments. No configuration changes required.<\/p>\n<h2><strong>Migrating Existing Indexes (Read carefully)<\/strong><\/h2>\n<p>If you created DiskANN indexes during the <strong>November preview<\/strong>, they use an older data structure. To get the new capabilities, you\u2019ll need to <strong>drop and recreate<\/strong> them.<\/p>\n<blockquote><p><strong>\u26a0\ufe0f IMPORTANT: Query syntax changes after migration<\/strong><\/p>\n<p>The new index version uses improved syntax that removes previous limitations. The TOP_N parameter is <strong>no longer supported<\/strong> in favor of the new SELECT TOP (N) WITH APPROXIMATE syntax<\/p>\n<p><strong>Before migrating<\/strong>, update your application code to use the new syntax. If you migrate the index without updating your queries, vector searches will fail as the new index does not support the explicit TOP_N parameter.<\/p>\n<p>For detailed Migration Guidance check the documentation <a href=\"\/\/learn.microsoft.com\/sql\/t-sql\/statements\/create-vector-index-transact-sql#migrating-from-earlier-vector-index-versions\">here<\/a> .<\/p><\/blockquote>\n<p>With migration and query updates out of the way, the most important change becomes immediately visible.<!--ScriptorEndFragment--><\/p>\n<h2><strong>Full DML Support\u00a0<\/strong><\/h2>\n<p>This is the big one! Tables with vector indexes are no longer read-only. You can freely insert, update, delete, and merge rows without dropping the index or enabling special configurations like ALLOW_STALE_VECTOR_INDEX.<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">--For example we delete a row\r\nDELETE FROM dbo.wikipedia_articles WHERE id = 9999;\r\n\r\n-- Run a vector search immediately - the deleted row won't appear\r\nSELECT TOP (10) WITH APPROXIMATE\r\n    t.id, t.title, s.distance\r\nFROM VECTOR_SEARCH(\r\n    TABLE = wikipedia_articles AS t,\r\n    COLUMN = title_vector,\r\n    SIMILAR_TO = @query_vector,\r\n    METRIC = 'cosine'\r\n) AS s\r\nORDER BY s.distance;<\/code><\/pre>\n<p>The deleted row is immediately invisible to queries. The background maintenance handles cleanup asynchronously.<\/p>\n<h3>Observing Background Maintenance<\/h3>\n<p>Full DML support works because DiskANN indexes are maintained <strong>asynchronously<\/strong>.<\/p>\n<ul>\n<li>When you insert, update, or delete rows, your transaction commits without waiting for the index to update. The DML operation isn&#8217;t blocked by index maintenance, and those changes are <strong><strong>visible to vector search queries right away.<\/strong><\/strong><\/li>\n<li>In the background, the system queues the updates and gradually incorporates them into the <strong>DiskANN graph structure<\/strong>. Your application keeps running, queries keep executing, and the index optimizes itself without requiring you to pause writes or rebuild indexes.<\/li>\n<\/ul>\n<p>This asynchronous design is what makes <strong>operational RAG<\/strong> possible in SQL: Live data, continuous ingestion, and Vector search that stays online.<\/p>\n<p>If you\u2019re curious to observe this process, you can peek under the hood using the sys.dm_db_vector_indexes DMV:<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT \r\n    OBJECT_NAME(object_id) AS table_name,\r\n    approximate_staleness_percent,\r\n    last_background_task_succeeded,\r\nFROM sys.dm_db_vector_indexes;\r\n<\/code><\/pre>\n<p><em>approximate_staleness_percent<\/em> indicates the proportion of recent changes that have not yet been fully incorporated into the<strong> DiskANN graph.<\/strong> Because index maintenance is asynchronous, this value <strong>typically fluctuates<\/strong> over time, especially in workloads with continuous inserts or updates. There is nothing you need to tune or manage as the system handles it automatically<\/p>\n<p>Even when staleness is non\u2011zero, recently inserted or updated rows remain queryable. Search esults may be slightly less optimal in terms of recall until those changes are fully integrated, but rows are not omitted from query results.<\/p>\n<h2 id=\"query-syntax-changes\"><strong>Query Syntax and Iterative Filtering<\/strong><\/h2>\n<p>This update introduces a new query syntax and a more efficient way to apply filters during vector search.\nVector search now uses: <strong><code>TOP (N) WITH APPROXIMATE<\/code><\/strong><\/p>\n<ul>\n<li>By specifying <code>WITH APPROXIMATE<\/code>, you\u2019re indicating that <strong>approximate results are acceptable<\/strong>.<\/li>\n<li>The optimizer then decides whether to use the DiskANN index or exact KNN based on data size, predicates, and cost.<\/li>\n<\/ul>\n<p>With Iterative Filtering filters are no longer applied after the vector search completes. Instead, predicates are evaluated <strong>during<\/strong> the search itself. This removes the need to over\u2011fetch vectors and ensures you get the number of results you ask for.<\/p>\n<p>Here&#8217;s a quick look side by side to see the difference clearly:<\/p>\n<table>\n<thead>\n<tr>\n<th><strong>Before (Post-Filtering)<\/strong><\/th>\n<th><strong>New Version (Iterative Filtering)<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>The Problem:<\/strong> Filtering happened <em>after<\/em> retrieving vectors<\/td>\n<td><strong>The Solution:<\/strong> Filtering happens <em>during<\/em> the search<\/td>\n<\/tr>\n<tr>\n<td>You had to over-fetch and hope enough matched<\/td>\n<td>You get exactly the number of results requested<\/td>\n<\/tr>\n<tr>\n<td>\n<pre class=\"prettyprint language-sql\"><code class=\"language-default\">SELECT TOP (20) t.id, t.title, s.distance\r\nFROM VECTOR_SEARCH(\r\n    TABLE = wikipedia_articles,\r\n    COLUMN = title_vector,\r\n    SIMILAR_TO = @query_vector,\r\n    METRIC = 'cosine',\r\n    TOP_N = 20  -- Over-fetch!\r\n) AS s\r\nWHERE category = 'Technology'\r\nORDER BY s.distance;<\/code><\/pre>\n<\/td>\n<td>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT TOP (10) WITH APPROXIMATE\r\n    t.id, t.title, s.distance\r\nFROM VECTOR_SEARCH(\r\n    TABLE = wikipedia_articles AS t,\r\n    COLUMN = title_vector,\r\n    SIMILAR_TO = @query_vector,\r\n    METRIC = 'cosine'\r\n) AS s\r\nWHERE t.category = 'Technology'\r\nORDER BY s.distance;<\/code><\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td><strong>Result:<\/strong> Maybe 10 results, maybe 3, maybe 0<\/td>\n<td><strong>Result:<\/strong> Exactly 10 Technology articles<\/td>\n<\/tr>\n<tr>\n<td>Had to guess how many to fetch (TOP_N = 20? 100?)<\/td>\n<td>No guessing needed<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2><strong>Query Optimizer at work<\/strong><\/h2>\n<p>Here&#8217;s the power of this approach, As your application grows, the Exact same VECTOR_SEARCH query continues to work while the optimizer adjusts the execution strategy for you:<\/p>\n<table>\n<thead>\n<tr>\n<th>Environment<\/th>\n<th>What Happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Early development <\/strong>(no index yet)<\/td>\n<td>VECTOR_SEARCH falls back to exact KNN, allowing you to test query logic even before creating indexes.<\/td>\n<\/tr>\n<tr>\n<td><strong>Development <\/strong>(hundreds of rows)<\/td>\n<td>The optimizer may still choose exact KNN, even if a DiskANN index exists.<\/td>\n<\/tr>\n<tr>\n<td><strong>Staging <\/strong>(thousands of rows)<\/td>\n<td>The optimizer evaluates predicate selectivity and cost to choose between KNN and DiskANN.<\/td>\n<\/tr>\n<tr>\n<td><strong>Production <\/strong>(millions of rows)<\/td>\n<td>The optimizer leverages DiskANN with iterative filtering for scalable vector search.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Try It Yourself<\/h2>\n<p>We have put together a simple Quick Start script that demonstrates all these new capabilities in action. The sample uses Wikipedia article embeddings for semantic search and can be found on our Github repo <a href=\"https:\/\/github.com\/Azure-Samples\/azure-sql-db-vector-search\/tree\/main\/DiskANN\">DiskANN Vector Search Quickstart<\/a>.<\/p>\n<h2>What&#8217;s Next<\/h2>\n<p>These improvements make DiskANN much more practical for production RAG scenarios. While this is still a public preview with some <a href=\"https:\/\/learn.microsoft.com\/sql\/t-sql\/functions\/vector-search-transact-sql?view=sql-server-ver17#limitations\">limitations<\/a>, the major blockers are now resolved.<\/p>\n<p>For comprehensive documentation and up-to-date information on current capabilities, see:<\/p>\n<p>For complete documentation on DiskANN Vector indexes, including detailed syntax examples and current limitations, see:<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-in\/sql\/t-sql\/functions\/vector-search-transact-sql?view=sql-server-ver17\">VECTOR_SEARCH (Transact-SQL)<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/sql\/t-sql\/statements\/create-vector-index-transact-sql?view=sql-server-ver17\">CREATE VECTOR INDEX (Transact-SQL)<\/a><\/li>\n<li><a href=\"https:\/\/techcommunity.microsoft.com\/blog\/sqlserver\/announcing-public-preview-of-diskann-in-sql-server-2025\/4414683\">Understanding KNN and ANN<\/a><\/li>\n<\/ul>\n<p>Give it a try and let us know what you think! As always, your <a href=\"https:\/\/feedback.azure.com\/d365community\/forum\/04fe6ee0-3b25-ec11-b6e6-000d3a4f0da0\">feedback<\/a> helps shape where we go next with Vector Search in SQL.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Remember when we announced the Public Preview of DiskANN vector indexes back in November and mentioned that once you created the index, your table became read\u2011only? Yeah\u2026 about that&#8230; \ud83d\ude05 We shipped early because the demand for Vector search in SQL was overwhelming. We knew the constraints weren\u2019t ideal, but we also knew the fastest [&hellip;]<\/p>\n","protected":false},"author":24720,"featured_media":81,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[599,1,594,572,619,615],"tags":[602,588,676,677,591,647],"class_list":["post-6730","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-openai","category-azure-sql","category-hyperscale","category-managed-instance","category-t-sql","category-vectors","tag-azure-openai","tag-azure-sql-db","tag-diskann","tag-vector-index","tag-vector-search","tag-vectors"],"acf":[],"blog_post_summary":"<p>Remember when we announced the Public Preview of DiskANN vector indexes back in November and mentioned that once you created the index, your table became read\u2011only? Yeah\u2026 about that&#8230; \ud83d\ude05 We shipped early because the demand for Vector search in SQL was overwhelming. We knew the constraints weren\u2019t ideal, but we also knew the fastest [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6730","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/24720"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=6730"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6730\/revisions"}],"predecessor-version":[{"id":6773,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/6730\/revisions\/6773"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/81"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=6730"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=6730"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=6730"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}