Skip to main content
🎉 All exam preparation materials are available for free until 31 August 2026.

Last updated: August 2026

Practice Exam

DP-800SQL AI Developer Associate

Test your knowledge with official exam-style questions

Questions25Passing700Exam time120 min

Questions and options are shuffled each attempt

Microsoft Certified: SQL AI Developer AssociatePractice Set 1: All Questions & Explanations

Full question text, answer options, and explanations for this practice set — a spoiler-free alternative is the interactive quiz above for scored, shuffled practice.

  1. 1. A developer needs to store product reviews in an Azure SQL database. The reviews arrive as JSON documents and must be queryable by specific JSON properties. Which column type should the developer use to store these documents while still enabling JSON-specific indexing?

    • A. NVARCHAR(MAX) with a computed column and JSON index
    • B. JSON column type with a JSON index(correct)
    • C. VARBINARY(MAX) with manual serialization
    • D. XML column type with XQuery predicates

    Explanation: Azure SQL and SQL Server support a native JSON column type that can be paired with a JSON index to enable efficient querying of JSON properties. NVARCHAR(MAX) with a computed column (A) is the legacy approach that predates the native JSON type and does not support JSON-native indexing. VARBINARY(MAX) (C) stores binary data and is not queryable via JSON functions. XML columns (D) use a completely different data format and indexing mechanism that does not apply to JSON.

  2. 2. A database architect needs to ensure that historical data in an Orders table is automatically retained so that queries can retrieve the state of any row as it existed at any point in the past two years. Which specialized table type satisfies this requirement with the least custom development effort?

    • A. In-memory optimized table
    • B. Temporal table(correct)
    • C. Ledger table
    • D. External table

    Explanation: Temporal tables automatically maintain a history table with system-managed start/end time columns, allowing point-in-time queries using the FOR SYSTEM_TIME clause. In-memory optimized tables (A) improve performance for OLTP workloads but do not track row history. Ledger tables (C) provide tamper-evident history for compliance but are not designed for general point-in-time retrieval using time-travel syntax. External tables (D) reference data outside the database and have no built-in row history.

  3. 3. A developer needs to write a T-SQL query that calculates a running total of sales per customer, ordered by sale date, without using a GROUP BY clause that collapses rows. Which T-SQL construct should be used?

    • A. A correlated subquery referencing the outer query's CustomerID
    • B. A window function using SUM() OVER (PARTITION BY CustomerID ORDER BY SaleDate)(correct)
    • C. A scalar function that loops through all rows for a given customer
    • D. A common table expression (CTE) with a HAVING clause

    Explanation: Window functions with an OVER clause allow aggregate calculations (like running totals) to be performed across a set of rows related to the current row without collapsing the result set. A correlated subquery (A) can compute running totals but is much less efficient and more complex. A scalar function with a loop (C) is a cursor-like anti-pattern that performs poorly at scale. A CTE with HAVING (D) filters grouped aggregates, which collapses rows rather than preserving individual row detail.

  4. 4. A developer is working on a SQL database in Microsoft Fabric and wants to use GitHub Copilot Chat to help write a complex stored procedure. Before starting, the team's security officer needs to understand the data exposure risks. Which security consideration is most important when using GitHub Copilot with database code in this context?

    • A. GitHub Copilot encrypts all prompts using Always Encrypted before sending them to the model
    • B. Code and schema context included in the prompt may be transmitted to the underlying language model, which could expose sensitive database structure or data samples(correct)
    • C. GitHub Copilot requires Row-Level Security to be disabled on all referenced tables before generating suggestions
    • D. GitHub Copilot suggestions are guaranteed to be free of SQL injection vulnerabilities

    Explanation: When using AI-assisted tools like GitHub Copilot, the prompt context — which may include schema definitions, table names, column names, sample data, or inline comments — is sent to the language model. This represents a potential data exposure risk that security officers must evaluate before enabling Copilot with sensitive database code. Copilot does not apply Always Encrypted to its prompts (A). RLS does not need to be disabled for Copilot to function (C). Copilot suggestions are not guaranteed secure and must be reviewed for SQL injection and other vulnerabilities (D).

  5. 5. A developer is configuring a GitHub Copilot session to assist with writing T-SQL for a Microsoft Fabric SQL database. They want to connect to additional context sources. Which two actions can the developer take to extend GitHub Copilot's context using Model Context Protocol (MCP)? Choose 2.

    • A. Connect to an MCP server endpoint for Microsoft SQL Server to give Copilot live schema context(correct)
    • B. Configure model and MCP tool options within the GitHub Copilot chat session settings
    • C. Enable dynamic data masking on all tables before connecting to MCP
    • D. Replace GitHub Copilot with a third-party AI assistant that supports MCP natively
    • E. Connect to a Fabric lakehouse MCP server endpoint to provide data context(correct)

    Explanation: The DP-800 skills guide explicitly lists 'Connect to MCP server endpoints, including Microsoft SQL Server and Fabric lakehouse' as a measured skill. Connecting to these MCP endpoints gives Copilot live schema and data context to improve code generation quality. Configuring model and MCP tool options (B) is a related skill but refers to settings within the session rather than the act of connecting to specific endpoints. Dynamic data masking (C) is a security feature unrelated to MCP connectivity. Replacing Copilot (D) is out of scope. Option E is specifically named in the skill bullet.

  6. 6. A developer needs to write a T-SQL query to find all product names that are within an edit distance of 2 from a user-supplied search string, to support fuzzy search functionality. Which function should the developer use?

    • A. SOUNDEX()
    • B. DIFFERENCE()
    • C. EDIT_DISTANCE()(correct)
    • D. PATINDEX()

    Explanation: EDIT_DISTANCE() is a T-SQL function specifically designed to compute the Levenshtein edit distance between two strings, making it ideal for fuzzy string matching based on character-level differences. SOUNDEX() (A) encodes strings by their phonetic sound rather than character similarity, which is not the same as edit distance. DIFFERENCE() (B) compares SOUNDEX values and returns a similarity score of 0-4, not an edit distance. PATINDEX() (D) returns the starting position of a pattern in a string and does not compute edit distance.

  7. 7. A developer needs to model a social network where users can follow other users in a SQL database. Queries will frequently ask 'find all friends of friends within 3 hops'. Which table type and query pattern is most appropriate?

    • A. A standard relational self-join table with recursive CTEs
    • B. A graph table with NODE and EDGE tables, queried using the MATCH operator(correct)
    • C. A temporal table with history partitioned by relationship depth
    • D. An in-memory optimized table with compiled stored procedures

    Explanation: SQL Server and Azure SQL support graph tables (NODE and EDGE table types) and the MATCH operator, which is purpose-built for traversing graph relationships like 'friends of friends' across multiple hops with concise syntax. Recursive CTEs with self-join (A) can express graph traversal but are more verbose, harder to optimize, and not as naturally suited to arbitrary-depth traversal. Temporal tables (C) track row history over time and are unrelated to graph relationships. In-memory tables (D) improve OLTP performance but do not simplify graph query patterns.

  8. 8. A developer is building a stored procedure that performs multiple DML operations as a batch. If any single statement fails, the entire batch should be rolled back and a meaningful error message returned to the caller. Which T-SQL construct achieves this?

    • A. A GOTO statement that jumps to a cleanup label at the bottom of the procedure
    • B. A TRY...CATCH block wrapping all DML statements, with ROLLBACK TRANSACTION and THROW in the CATCH block(correct)
    • C. Setting XACT_ABORT OFF and checking @@ERROR after every statement
    • D. Using a RAISERROR statement at the beginning of the procedure to pre-empt failures

    Explanation: A TRY...CATCH block is the standard T-SQL error handling mechanism. The DML statements run inside TRY; if any error occurs, execution jumps to CATCH where ROLLBACK TRANSACTION undoes all changes and THROW or RAISERROR returns the error to the caller. GOTO (A) can be made to work but is error-prone and not the modern recommended pattern. Checking @@ERROR (C) is the old T-SQL pattern; it does not catch all error severities and is fragile. RAISERROR at the start (D) cannot pre-empt future runtime failures.

  9. 9. A developer is writing a T-SQL query to extract all order line items from a JSON column named OrderDetails. Each row's OrderDetails value contains a JSON array of objects with properties 'ProductId', 'Quantity', and 'UnitPrice'. The developer needs each array element to appear as a separate row in the result set. Which function is the correct choice?

    • A. JSON_VALUE(OrderDetails, '$.ProductId')
    • B. JSON_QUERY(OrderDetails, '$')
    • C. OPENJSON(OrderDetails) WITH (ProductId INT, Quantity INT, UnitPrice DECIMAL(10,2))(correct)
    • D. JSON_ARRAYAGG(OrderDetails)

    Explanation: OPENJSON() is the T-SQL table-valued function that parses a JSON string and returns its contents as rows and columns, making it ideal for shredding a JSON array into individual relational rows. The WITH clause defines the output schema. JSON_VALUE() (A) extracts a single scalar value from a JSON path — it does not expand arrays into rows. JSON_QUERY() (B) extracts a JSON fragment (object or array) but does not convert it to rows. JSON_ARRAYAGG() (D) aggregates multiple rows into a JSON array — the opposite of what is needed here.

  10. 10. A developer needs to create a GitHub Copilot instruction file to guide Copilot's behavior when generating T-SQL code for their project. Where should this instruction file be placed in a GitHub repository?

    • A. In the root of the repository as .copilot-instructions.txt
    • B. In the .github directory as copilot-instructions.md(correct)
    • C. In a /instructions subfolder anywhere in the repository tree
    • D. In the repository's Settings tab as a repository secret named COPILOT_INSTRUCTIONS

    Explanation: GitHub Copilot custom instruction files are placed in the .github directory and named copilot-instructions.md. This is the standard, recognized location that GitHub Copilot reads automatically when providing suggestions in that repository. A .copilot-instructions.txt at the root (A) is not the recognized file name or location for this feature. A /instructions subfolder (C) is not the standard Copilot convention. Repository secrets (D) are for encrypted environment variables, not instruction content.

  11. 11. A compliance team requires that the SocialSecurityNumber column in a Customers table is never readable in plaintext by database administrators or the application layer — decryption must happen only on the client side. Which encryption feature should be implemented?

    • A. Transparent Data Encryption (TDE)
    • B. Column-level encryption using ENCRYPTBYPASSPHRASE
    • C. Always Encrypted(correct)
    • D. Dynamic Data Masking

    Explanation: Always Encrypted is designed so that SQL Server never sees plaintext for the encrypted columns — encryption and decryption happen exclusively in the client driver using keys that the server never holds. TDE (A) encrypts data at rest on disk but does not protect against DBAs or privileged server-side access seeing plaintext. Column-level encryption with ENCRYPTBYPASSPHRASE (B) encrypts values in the database but decryption still occurs server-side with T-SQL, so a DBA can decrypt it. Dynamic Data Masking (D) obfuscates data in query results but does not encrypt it — a privileged user can still unmask the data.

  12. 12. A developer wants to ensure that users in the Sales role can only see rows in the Orders table where the SalesRepId matches their own database login. Other users should be blocked from seeing those rows entirely. Which security feature should be implemented?

    • A. Dynamic Data Masking on the SalesRepId column
    • B. Row-Level Security (RLS) with a security predicate function(correct)
    • C. A view that filters rows by SalesRepId
    • D. Object-level DENY permissions on the Orders table

    Explanation: Row-Level Security (RLS) enforces access at the row level by binding a security predicate function to a table; every query against that table is automatically filtered based on the predicate, regardless of how the query is constructed. Dynamic Data Masking (A) hides data values in query results but does not prevent rows from being returned. A view (C) can filter rows but can be bypassed if the user has direct table access, and it does not scale as cleanly as RLS. DENY on the whole table (D) would block the user from accessing any rows at all, not just rows for other sales reps.

  13. 13. An Azure SQL database is experiencing sudden query slowdowns. The DBA suspects blocking. They need to identify long-running transactions that are blocking other sessions and view the query text responsible for the blocking head. Which tool or view is most appropriate for this real-time investigation?

    • A. Query Store reports in SSMS
    • B. Dynamic Management Views (DMVs) such as sys.dm_exec_requests and sys.dm_exec_sql_text(correct)
    • C. The Execution Plan in the Query Editor
    • D. Query Performance Insight in the Azure portal for historical averages

    Explanation: Dynamic Management Views (DMVs) like sys.dm_exec_requests expose real-time session-level data including blocking_session_id, wait_type, and the query text via sys.dm_exec_sql_text — exactly what is needed to diagnose active blocking in real time. Query Store (A) retains historical query plans and statistics but does not show live blocking information. Reviewing an execution plan in the Query Editor (C) shows how a single query would run, not which sessions are currently blocking each other. Query Performance Insight (D) shows aggregated historical data, not real-time blocking chains.

  14. 14. A development team is setting up a CI/CD pipeline for an Azure SQL database using SQL Database Projects. They want to prevent schema drift and control deployments through pull request approvals. Which two capabilities of SQL Database Projects directly support these requirements? Choose 2.

    • A. Detect schema drift by using SQL Database Projects(correct)
    • B. Design and implement controls for deployment pipelines, including branching policies and code owners(correct)
    • C. Enable Always Encrypted on all columns to prevent unauthorized schema changes
    • D. Implement Dynamic Data Masking to hide schema details from developers
    • E. Configure source control for SQL Database Projects to store schema definitions in Git

    Explanation: SQL Database Projects include built-in schema drift detection that compares the project model against the live database, alerting the team when the database schema has diverged from source control. Deployment pipeline controls (branching policies, code owners, approval gates) are a direct DP-800 skill that enforces pull request approval before schema changes are deployed. Always Encrypted (C) is a data security feature unrelated to schema drift detection. Dynamic Data Masking (D) is a runtime data obfuscation feature, not a schema control mechanism. Configuring source control (E) is foundational but does not by itself detect drift or enforce approvals.

  15. 15. A developer needs to expose data from an Azure SQL database as a REST API without writing custom API code. The API should support filtering, pagination, and searching. Which Azure service should be used?

    • A. Azure API Management with a manual OpenAPI specification
    • B. Data API builder (DAB) configured with entity definitions for REST endpoints(correct)
    • C. Azure Logic Apps with an SQL connector
    • D. An Azure Function with a custom HTTP trigger and EF Core queries

    Explanation: Data API builder (DAB) is specifically designed to expose SQL database entities as REST and GraphQL endpoints with minimal configuration — it supports filtering, pagination, and searching out of the box through configuration files and entity definitions. Azure API Management (A) is a gateway that manages existing APIs; it does not generate REST endpoints directly from SQL schemas. Azure Logic Apps (C) is a workflow automation tool, not an API generation platform. An Azure Function with EF Core (D) works but requires significant custom code — the opposite of 'without writing custom API code'.

  16. 16. A developer needs to react to every INSERT on a SQL database table and immediately generate an embedding for the new row and store it in a separate vector table, keeping it in sync with near-zero latency. Which change-tracking mechanism is best suited for this row-level, event-driven embedding pipeline?

    • A. Azure Functions with SQL trigger binding, which fires on each DML change event(correct)
    • B. A batch job using Change Tracking queried every hour
    • C. CDC (Change Data Capture) replicated to an Azure Storage account nightly
    • D. Query Store capturing all INSERT statements for offline processing

    Explanation: Azure Functions with SQL trigger binding is an event-driven mechanism that fires a function in near real-time when rows are inserted, updated, or deleted in a SQL table, making it ideal for immediately generating and storing embeddings on each new row. A batch job using Change Tracking (B) introduces latency proportional to the polling interval — near-zero latency is not achievable. CDC replicated nightly (C) introduces 24-hour latency, which is far from near-zero. Query Store (D) captures query performance data, not a row-change event trigger for downstream processing.

  17. 17. A developer is configuring a Data API builder (DAB) deployment and needs to ensure the service authenticates to Azure SQL without storing a username or password in any configuration file. Which authentication approach should be configured?

    • A. Store the connection string including username and password in the DAB config file
    • B. Use a Managed Identity for the DAB hosting environment and configure Azure SQL to accept it(correct)
    • C. Use SQL Server Authentication with a service account and rotate the password every 90 days
    • D. Embed the database password in a GitHub Actions secret and inject it at deploy time

    Explanation: Passwordless authentication using Managed Identity eliminates stored credentials entirely. The DAB host (App Service, Container App, etc.) receives an Azure AD token automatically, and Azure SQL is configured to grant access to that identity. Storing credentials in the config file (A) violates secrets management best practices and creates credential exposure risk. SQL Server Authentication with rotation (C) still relies on a password that must be stored and managed securely. Injecting a password via GitHub Actions secrets (D) reduces human exposure but still means a password exists and must be managed.

  18. 18. A team is implementing a CI/CD pipeline for a SQL Database Project in GitHub Actions. They want to ensure that only reviewed, approved code reaches the production database and that all deployment secrets are protected. Which two practices should they implement? Choose 2.

    • A. Implement secrets management to store database credentials securely, preventing them from being hardcoded in workflow files(correct)
    • B. Set XACT_ABORT ON in every deployment script to catch transactional errors
    • C. Configure branching policies and code owners to require pull request approval before merging schema changes(correct)
    • D. Grant the pipeline service principal db_owner rights on all databases to ensure deployment always succeeds
    • E. Store connection strings in clear text in the repository for developer convenience

    Explanation: Secrets management (A) ensures database credentials are stored in a secure vault (e.g., GitHub encrypted secrets or Azure Key Vault) rather than in plain text in workflow files — a direct DP-800 CI/CD skill. Branching policies with code owners (C) enforce that pull requests must be reviewed and approved before schema changes are deployed to production, preventing unauthorized changes. XACT_ABORT ON (B) is a useful session setting but is not a CI/CD pipeline control. Granting db_owner broadly (D) violates least-privilege principles. Storing connection strings in clear text (E) is a critical security violation.

  19. 19. A developer has exposed a stored procedure through Data API builder (DAB) as a GraphQL mutation. They need to ensure the DAB service itself and any external clients can be secured at the endpoint level. Additionally, the team uses Azure Monitor for observability. Which combination of actions should the developer take?

    • A. Secure GraphQL endpoints and configure Azure Monitor with Application Insights for logging(correct)
    • B. Disable GraphQL and use only REST endpoints, then add a reverse proxy for security
    • C. Expose all stored procedures directly via public SQL port without DAB to avoid configuration complexity
    • D. Use Always Encrypted on the stored procedure's return values and ignore endpoint security

    Explanation: DP-800 skills include both 'Secure GraphQL, REST, and MCP endpoints' and 'Recommend Azure Monitor configurations, including Application Insights and Log Analytics'. Securing the GraphQL endpoint (via authentication policies in DAB configuration) and integrating Application Insights for telemetry is the correct, layered approach. Disabling GraphQL (B) is unnecessary and reduces functionality. Exposing SQL directly (C) eliminates all the security and abstraction benefits of DAB. Using Always Encrypted on return values (D) addresses data-at-rest confidentiality but does not secure the GraphQL endpoint itself.

  20. 20. A developer wants to generate vector embeddings for product descriptions stored in an Azure SQL database. Before choosing an embedding model, they need to evaluate several external models for this use case. Which factor is most critical when evaluating models for generating text embeddings that will be stored and queried in the database?

    • A. The model's image generation capability
    • B. The embedding vector dimensions output by the model, which must match the database column's vector size(correct)
    • C. The model's support for generating SQL queries
    • D. The model's training dataset release date

    Explanation: When storing embeddings in a database vector column, the vector dimensions produced by the model must exactly match the size configured for the vector column. A mismatch causes storage or query errors. If embeddings are generated with a 1536-dimension model but the column is defined for 768 dimensions, the solution breaks. Image generation capability (A) is irrelevant for text embeddings. SQL query generation (C) is an unrelated model capability. Training dataset release date (D) may affect knowledge quality but is not the critical technical factor for embedding compatibility with a database column.

  21. 21. A developer is implementing semantic vector search in Azure SQL. They have generated embeddings for a product catalog and stored them in a vector column. The search query must find the top 10 most semantically similar products to a user's query embedding. Which function and pattern should be used?

    • A. FREETEXT() against the product description column, ordered by relevance rank
    • B. VECTOR_SEARCH() or VECTOR_DISTANCE() with an ORDER BY clause to rank results by similarity(correct)
    • C. SOUNDEX() comparison of the user query against product names
    • D. EDIT_DISTANCE() between the query text and each product description

    Explanation: VECTOR_SEARCH() and VECTOR_DISTANCE() are the T-SQL functions for semantic vector similarity search. VECTOR_DISTANCE() computes a distance metric (cosine, dot product, Euclidean) between two vectors, and ordering results ascending by distance returns the most similar items. FREETEXT() (A) performs full-text keyword search, not semantic vector search — it does not use embeddings. SOUNDEX() (C) is a phonetic algorithm for string similarity, not vector similarity. EDIT_DISTANCE() (D) computes character-level string distance, not semantic embedding distance.

  22. 22. A developer is building a Retrieval-Augmented Generation (RAG) application using Azure SQL. After retrieving relevant chunks from the database via vector search, they need to send those results to an external language model endpoint from within T-SQL. Which stored procedure enables this?

    • A. sp_execute_external_script
    • B. sp_invoke_external_rest_endpoint(correct)
    • C. sp_send_dbmail
    • D. sp_executesql

    Explanation: sp_invoke_external_rest_endpoint is the T-SQL stored procedure that allows Azure SQL to make HTTP REST calls to external endpoints — including language model APIs — directly from T-SQL. This is explicitly listed in the DP-800 RAG skill: 'Create a prompt by using the sp_invoke_external_rest_endpoint stored procedure'. sp_execute_external_script (A) runs external scripts (R, Python) in SQL Server Machine Learning Services, not arbitrary REST calls. sp_send_dbmail (C) sends email messages. sp_executesql (D) executes dynamic T-SQL strings, not external HTTP calls.

  23. 23. A developer is designing the chunking strategy for a RAG application built on Azure SQL. The source data consists of lengthy technical manuals stored as text in a SQL table. The developer must balance retrieval precision with context completeness. Which chunking approach is most appropriate?

    • A. Store each entire manual as a single embedding chunk to preserve full context
    • B. Split each manual into fixed-size overlapping chunks, generate one embedding per chunk, and store each chunk with its source reference(correct)
    • C. Use SOUNDEX() to group similar sentences and embed each phonetic group
    • D. Generate a single embedding for the table name and use it for all queries against that table

    Explanation: Fixed-size overlapping chunks balance context completeness (overlap prevents important information from being split across chunk boundaries) and retrieval precision (smaller chunks produce more focused embeddings that match narrow queries better). Storing entire manuals as one chunk (A) generates very coarse embeddings that perform poorly on specific queries and may exceed model context limits. SOUNDEX grouping (C) is a phonetic algorithm with no relevance to semantic chunking. A single embedding for the table name (D) provides no meaningful semantic signal about the content.

  24. 24. A developer is designing a hybrid search system in Azure SQL that combines full-text search and vector (semantic) search results into a single ranked result list. Which two components are required to merge and rank results from both search methods? Choose 2.

    • A. Reciprocal rank fusion (RRF) to combine rankings from both search result sets into a single unified ranking(correct)
    • B. Full-text search using FREETEXT() or CONTAINSTABLE() for keyword-based matching(correct)
    • C. Dynamic Data Masking on the vector column to protect embedding values
    • D. OPENJSON() to parse the vector column before performing similarity calculations
    • E. Graph tables with the MATCH operator to traverse search result relationships

    Explanation: Hybrid search combines keyword (full-text) search and semantic (vector) search. Full-text search via FREETEXT() or CONTAINSTABLE() (B) provides the keyword-based ranked result set. Reciprocal rank fusion (RRF) (A) is the standard algorithm for merging and re-ranking results from multiple ranked lists into a single unified ranking — explicitly listed as a DP-800 hybrid search skill. Dynamic Data Masking (C) is a security feature unrelated to search ranking. OPENJSON() (D) is for parsing JSON arrays, not vector similarity. Graph tables (E) are for relationship traversal, not search result merging.

  25. 25. A developer needs to choose between Approximate Nearest Neighbor (ANN) and Exact Nearest Neighbor (ENN) search for a product recommendation feature in Azure SQL. The product catalog has 10 million rows. Query response time must be under 200ms. Which search mode should be used and why?

    • A. ENN, because it guarantees finding the mathematically closest vectors and the catalog is small enough
    • B. ANN, because it uses a vector index to find approximate nearest neighbors much faster than scanning all rows, trading a small precision loss for dramatically lower latency at scale(correct)
    • C. Full-text search, because it does not require embedding generation and is always faster than vector search
    • D. ENN with a hash index, which provides the speed of ANN with the precision of ENN

    Explanation: At 10 million rows, ENN (brute-force exhaustive scan) would require comparing every vector in the table, making sub-200ms response impossible. ANN uses a vector index (such as HNSW or IVF-based structures) to retrieve approximate nearest neighbors in logarithmic time, achieving very low latency at the cost of a small, acceptable precision trade-off. ENN (A) is impractical at 10M rows for real-time queries. Full-text search (C) does not perform semantic similarity and would not find semantically related products. A 'hash index for ENN' (D) is not a real Azure SQL vector search capability; hash indexes are used for equality lookups, not nearest-neighbor search.