{"id":7446,"date":"2026-08-18T11:40:38","date_gmt":"2026-08-18T18:40:38","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=7446"},"modified":"2026-08-18T12:01:33","modified_gmt":"2026-08-18T19:01:33","slug":"two-hybrid-search","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/two-hybrid-search\/","title":{"rendered":"The Two Hybrid Searches in Microsoft SQL"},"content":{"rendered":"<p>Hybrid search is usually described as combining keyword search with vector search. Microsoft SQL does that, for sure, but we do quite a bit more right out of the box. SQL dynamically evaluates queries and switches between kNN and ANN vector search based on cost and selectivity. These two types of hybrid search, work together, ensuring your semantic queries return the best possible results to your apps and agents.<\/p>\n<h3>Text search<\/h3>\n<p>In 1998, Microsoft Research Cambridge welcomed Stephen Robertson, one of the principal architects of BM25, or Best Matching 25, the relevance-ranking algorithm that became foundational to modern information retrieval. Robertson spent the next 15 years at Microsoft Research, and SQL Server embraced full-text search early. Today, <code data-start=\"330\" data-end=\"347\">FREETEXTTABLE()<\/code> still uses BM25 to rank results by relevance. Vector search may feel new, but relevance-ranked search has been part of the SQL story for decades.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>The magic of FREETEXTTABLE()<\/strong><\/p>Unlike Microsoft SQL&#8217;s `CONTAINSTABLE()`, which searches text using precise terms, phrases, prefixes, proximity, and explicit inflectional forms, `FREETEXTTABLE()` is designed for broad, relevance-ranked retrieval.<\/p>\n<p>&nbsp;<\/p>\n<p>It automatically applies language-aware word breaking and stemming to expand user input across related word forms. The user queries for &#8220;run,&#8221; but the engine understands &#8220;ran,&#8221; &#8220;running,&#8221; and &#8220;runs&#8221; without any extra clarification. This makes text search in SQL especially useful when users describe what they want rather than knowing the exact words stored in the data.<\/div><\/p>\n<h4>Sample syntax<\/h4>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT p.Name, ft.RANK\r\nFROM FREETEXTTABLE(Product, (Description), 'running shoes') ft\r\nJOIN Product p ON p.Id = ft.[KEY]\r\nORDER BY ft.RANK DESC;<\/code><\/pre>\n<p><div  class=\"d-flex justify-content-left\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/system-functions\/freetexttable-transact-sql?view=sql-server-ver17\" target=\"_blank\">Learn more about FREETEXTTABLE()<\/a><\/div><\/p>\n<h3>Vector search<\/h3>\n<p>In 2025, SQL embraced DiskANN, another innovation born in Microsoft Research. First published in 2019, DiskANN showed that approximate vector search could remain fast and accurate across millions, even billions, of vectors without requiring enormous amounts of memory. The industry noticed, with other databases implementing DiskANN-inspired approaches of their own. Today, DiskANN is part and parcel of SQL&#8217;s approach to vector search, bringing that same research directly into the engine.<\/p>\n<p>kNN, or k-nearest neighbors, is the exact form of vector search. It compares the query vector against the available vectors and returns the closest matches according to the selected distance metric. It is simple and accurate, but the work grows with the size of the data set, which is why ANN becomes more useful at larger scale.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>The magic of VECTOR_SEARCH()<\/strong><\/p>Unlike Microsoft SQL&#8217;s <code>VECTOR_DISTANCE()<\/code>, which performs an exact comparison and never uses a vector index, <code>VECTOR_SEARCH()<\/code> is designed to retrieve the nearest matches efficiently across large vector sets. Predicates can even participate during the search through iterative filtering, helping SQL return the requested number of relevant rows without oversampling.<\/div><\/p>\n<h4>Sample syntax<\/h4>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT TOP (10) WITH APPROXIMATE\r\n    p.Id, p.Name, v.distance\r\nFROM VECTOR_SEARCH(\r\n    TABLE = ProductEmbedding AS p,\r\n    COLUMN = Embedding,\r\n    SIMILAR_TO = @Embedding,\r\n    METRIC = 'cosine'\r\n) AS v\r\nORDER BY v.distance;<\/code><\/pre>\n<p><div  class=\"d-flex justify-content-left\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/functions\/vector-search-transact-sql?view=sql-server-ver17\" target=\"_blank\">Learn more about VECTOR_SEARCH()<\/a><\/div><\/p>\n<h3>Model integration<\/h3>\n<p>In 2022, Azure SQL introduced <code>sp_invoke_external_rest_endpoint<\/code>, giving T-SQL a native way to call REST services directly from the database. Today, that capability underpins SQL&#8217;s growing model integration story, including External Models and built-in AI functions like <code>AI_GENERATE_EMBEDDINGS<\/code> that simplify integration. And when these built-in abstractions do not yet cover emerging interactions and models, the direct REST endpoint remains available, making scenarios such as GPT-based intent detection or Cohere reranking part of the same SQL-centered RAG pipeline.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Endpoints in Azure SQL database<\/strong><\/p><code>sp_invoke_external_rest_endpoint<\/code> is implemented a little differently in Azure SQL than in SQL Server. In both, credentials remain protected inside SQL and endpoint access requires explicit permissions. Azure SQL adds another layer of protection with an allowlist of approved service domains, including most major Azure services, Microsoft Graph, Power BI, and &#8211; perhaps most important here &#8211; Microsoft Foundry. Administrators can validate supported endpoints and use services such as API Management when they need to extend access beyond the built-in list.<\/div><\/p>\n<h4>Sample syntax<\/h4>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">DECLARE @Response NVARCHAR(MAX);\r\n\r\nEXEC sys.sp_invoke_external_rest_endpoint\r\n    @method = 'POST',\r\n    @url = 'https:\/\/example.com\/api',\r\n    @payload = N'{\"query\":\"running shoes\"}',\r\n    @response = @Response OUTPUT;<\/code><\/pre>\n<p><div  class=\"d-flex justify-content-left\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/system-stored-procedures\/sp-invoke-external-rest-endpoint-transact-sql?view=sql-server-ver17&amp;tabs=request-headers\" target=\"_blank\">Learn more about calling endpoints<\/a><\/div><\/p>\n<h3>Hybrid search<\/h3>\n<p>Now we bring them together. Full-text search finds the words that matter, while vector search finds the meaning behind them. Each produces its own ranked results, and Reciprocal Rank Fusion (RRF) combines those rankings into a single result set, optionally weighting one search more heavily than the other.<\/p>\n<h4>A typical workflow<\/h4>\n<p>Depending on your needs, a hybrid search flow can include several curation steps to help ensure user input is tuned for optimal search and fused results are ranked for optimal ordering. Every step in a comprehensive hybrid search flow can be orchestrated in SQL, helping enable apps without introducing unnecessary change or complexity.<\/p>\n<p><em>Here&#8217;s an example:<\/em><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/08\/hybrid-search-flow-2.webp\"><img decoding=\"async\" class=\"wp-image-7464 size-full aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/08\/hybrid-search-flow-2.webp\" alt=\"hybrid search flow 2 image\" width=\"382\" height=\"436\" srcset=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/08\/hybrid-search-flow-2.webp 382w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2026\/08\/hybrid-search-flow-2-263x300.webp 263w\" sizes=\"(max-width: 382px) 100vw, 382px\" \/><\/a><\/p>\n<p>This is where SQL becomes especially useful for RAG. Query rewriting and intent detection can improve the searches before they run, RRF can fuse the results, and reranking can refine the final order. The entire retrieval pipeline can stay close to the production data your apps and agents already depend on.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hybrid search is usually described as combining keyword search with vector search. Microsoft SQL does that, for sure, but we do quite a bit more right out of the box. SQL dynamically evaluates queries and switches between kNN and ANN vector search based on cost and selectivity. These two types of hybrid search, work together, [&hellip;]<\/p>\n","protected":false},"author":96788,"featured_media":7468,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[744,743],"tags":[746,591],"class_list":["post-7446","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hybrid-search","category-vector-search","tag-full-text-search","tag-vector-search"],"acf":[],"blog_post_summary":"<p>Hybrid search is usually described as combining keyword search with vector search. Microsoft SQL does that, for sure, but we do quite a bit more right out of the box. SQL dynamically evaluates queries and switches between kNN and ANN vector search based on cost and selectivity. These two types of hybrid search, work together, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/7446","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\/96788"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=7446"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/7446\/revisions"}],"predecessor-version":[{"id":7466,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/7446\/revisions\/7466"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/7468"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=7446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=7446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=7446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}