SQL Server

Câu hỏi phỏng vấn SQL Server

90+ câu hỏi phỏng vấn SQL Server — đáp án chi tiết, code mẫu, SQL Server 2025 (17.x), Azure SQL Hyperscale, Fabric, Linux.
Cách dùng: đọc câu hỏi, tự trả lời ra giấy/thành tiếng, sau đó so với đáp án. Đừng học thuộc — hiểu cốt lõi, tự diễn đạt.

A. Kiến trúc & cài đặt

1. SQL Server có những edition nào?

Developer (free, dev only, đầy đủ Enterprise features), Express (free, giới hạn 50GB database từ 2025, trước đây 10GB), Standard, Enterprise. Azure SQL là phiên bản managed cloud. Học/dev → Developer hoặc Express.

Express 2025 tăng từ 10GB lên 50GB — đây là thay đổi lớn cho small apps, side projects. Với 50GB, Express có thể chạy production cho nhiều ứng dụng vừa và nhỏ.

2. SQL Server cài trên Linux được không?

Được, từ SQL Server 2017. Docker image chính chủ Microsoft chạy trên Linux container. SQL Server 2025 hỗ trợ Ubuntu 22.04/24.04, RHEL 9, SLES 15. Có thể chạy trên Kubernetes, podman. Hỗ trợ Active Directory authentication trên Linux. Một số feature vẫn Windows-only: SSIS, SSRS, Stretch Database, FileTable.

SQL Server 2025 on Linux gần full feature parity với Windows, bao gồm cả Availability Groups, Machine Learning Services. Container image chính thức có thể pull từ mcr.microsoft.com/mssql/server:2025-latest.

3. Difference between SQL and T-SQL?

SQL là chuẩn ANSI. T-SQL (Transact-SQL) là phương ngữ của Microsoft, mở rộng với: variable, control flow (IF, WHILE), error handling (TRY/CATCH), stored procedure, function, IDENTITY, OUTPUT, MERGE, system function (@@).

4. Instance là gì?

1 cài đặt SQL Server. 1 server có thể có nhiều instance (DefaultNamed). Mỗi instance có process, RAM, port riêng.

5. SSMS, Azure Data Studio, sqlcmd — khác nhau?

  • SSMS: GUI mạnh nhất, Windows-only, miễn phí. Dev .NET chính.
  • Azure Data Studio: cross-platform, modern, notebook style.
  • sqlcmd: CLI, dùng cho script/automation.

B. Kiểu dữ liệu

6. VARCHAR vs NVARCHAR khác gì?

  • VARCHAR(n): ASCII, 1 byte/char.
  • NVARCHAR(n): Unicode (UTF-16), 2 byte/char.

Cho tiếng Việt/Nhật/Trung → bắt buộc NVARCHAR. Từ 2019, có UTF-8 collation cho phép VARCHAR lưu Unicode tiết kiệm byte hơn.

7. CHAR vs VARCHAR?

  • CHAR(n): cố định n byte, pad space.
  • VARCHAR(n): biến đổi, lưu thực + 2 byte length.

Dùng CHAR khi length cố định (mã quốc gia 2 ký tự). Còn lại VARCHAR.

8. DATETIME vs DATETIME2?

  • DATETIME: 8 bytes, range 1753 → 9999, precision 3.33ms.
  • DATETIME2(7): 6–8 bytes, range 0001 → 9999, precision 100ns.

Best practice 2025: luôn dùng DATETIME2.

9. Vì sao tránh FLOAT cho tiền?

FLOAT là số gần đúng (IEEE 754). 0.1 + 0.2 ≠ 0.3. Tính tiền → DECIMAL(18, 2) chuẩn xác.

10. NULL vs '' (empty string) vs 0?

  • NULL = không xác định, không bằng gì kể cả NULL.
  • '' = chuỗi rỗng, có giá trị.
  • 0 = số 0 cụ thể.

Phải dùng IS NULL (không = NULL).

C. DDL & ràng buộc

11. Primary Key vs Unique Key?

PKUnique
NULLKhông1 NULL (SQL Server, khác chuẩn ANSI)
Số / bảng1Nhiều
Default indexClusteredNon-clustered

12. Foreign Key để làm gì? SQL Server có tự index FK không?

FK đảm bảo referential integrity — con phải có cha. SQL Server không tự tạo index trên FK column — nên tạo manual để JOIN nhanh.

13. ON DELETE CASCADE / SET NULL / NO ACTION khác gì?

  • CASCADE: xoá cha → xoá luôn con.
  • SET NULL: xoá cha → FK trong con thành NULL.
  • NO ACTION: chặn xoá cha nếu còn con tham chiếu (default).

14. Computed column và PERSISTED?

Cột tính từ cột khác. PERSISTED = lưu vật lý, index được. Không PERSISTED = tính khi query.

15. CHECK constraint?

Ràng buộc business rule trên giá trị: CHECK (Age >= 0 AND Age <= 150).

16. IDENTITY column?

Auto-increment. IDENTITY(seed, increment). Để get value vừa insert: SCOPE_IDENTITY() (an toàn nhất, scope hiện tại).

17. @@IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT()?

  • @@IDENTITY: identity cuối cùng trong session, kể cả từ trigger → có thể sai.
  • SCOPE_IDENTITY(): trong scope hiện tại → dùng cái này.
  • IDENT_CURRENT('table'): của bảng cụ thể, mọi session.

D. DML

18. DELETE vs TRUNCATE vs DROP?

DELETETRUNCATEDROP
LoạiDMLDDLDDL
WHERE
Reset IDENTITYN/A
TriggerN/A
Tốc độChậmNhanhNhanh nhất
Bảng còn?
Rollback trong tx

19. INSERT ... SELECT?

INSERT INTO ArchiveOrders (...)
SELECT ... FROM Orders WHERE OrderDate < '2025-01-01';

20. MERGE — dùng làm gì? Có gotcha không?

Upsert: INSERT nếu chưa có, UPDATE nếu có, có thể DELETE. SQL Server 2025 đã fix hầu hết edge case bugs từng gây tranh cãi — MERGE giờ ổn định hơn nhiều, test kỹ vẫn là best practice. Alternative an toàn: IF EXISTS ... UPDATE ... ELSE INSERT.

21. OUTPUT clause?

Trả về row đã insert/update/delete trong cùng statement:

INSERT INTO Audit OUTPUT INSERTED.* VALUES (...);
DELETE FROM Orders OUTPUT DELETED.* WHERE ...;

E. SELECT, JOIN, query

22. INNER vs LEFT vs FULL JOIN?

  • INNER: chỉ row match cả 2 bảng.
  • LEFT: tất cả row trái + match phải (NULL nếu không match).
  • FULL OUTER: tất cả row 2 bên.

23. LEFT JOIN ... WHERE bị bẫy ra sao?

Đặt điều kiện trên bảng phải ở WHERE → loại luôn row có NULL → biến thành INNER. Đặt vào ON.

24. NOT IN vs NOT EXISTS?

NOT IN cho kết quả sai nếu subquery có NULL. NOT EXISTS xử lý NULL đúng. Khuyến nghị: dùng NOT EXISTS.

25. UNION vs UNION ALL — cái nào nhanh?

UNION ALL nhanh hơn (không dedupe). Nếu chắc không trùng, dùng UNION ALL.

26. WHERE vs HAVING?

WHERE lọc trước GROUP BY, HAVING lọc sau (dùng được aggregate).

27. TOP vs OFFSET/FETCH?

  • SELECT TOP N: lấy N đầu.
  • OFFSET m ROWS FETCH NEXT n ROWS ONLY: pagination (chuẩn ANSI, từ 2012+).

28. ROW_NUMBER vs RANK vs DENSE_RANK?

Cùng input 100, 100, 90:

  • ROW_NUMBER: 1, 2, 3.
  • RANK: 1, 1, 3 (skip).
  • DENSE_RANK: 1, 1, 2 (no skip).

29. Lấy lương cao thứ N?

SELECT Salary FROM (
    SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) rk
    FROM Employees
) x WHERE rk = N;

30. Top N per group?

WITH Ranked AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Group ORDER BY Score DESC) rn
    FROM T
)
SELECT * FROM Ranked WHERE rn <= N;

31. CTE là gì? Khác subquery thế nào?

Common Table Expression — query tạm tên, reference nhiều lần trong cùng statement. Code dễ đọc hơn nested subquery. Hỗ trợ recursive (tree).

32. Recursive CTE — ví dụ?

Build org chart từ root xuống, traverse comment tree, BOM. Có anchor + recursive part nối bằng UNION ALL.

33. Khi nào dùng PIVOT?

Báo cáo: chuyển row → column. Doanh thu theo tháng, score theo môn học.

34. STRING_AGG dùng làm gì?

Gộp string trong group thành 1 string có separator (SQL Server 2017+):

STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name)

F. Index

35. Index hoạt động ra sao?

B-tree với key sorted. WHERE/JOIN trên cột index → seek O(log n) thay vì O(n). Trade-off: tốn space, slow INSERT/UPDATE.

36. Clustered vs Non-clustered?

  • Clustered: sort vật lý data theo key, 1 cái/bảng, leaf chứa data.
  • Non-clustered: B-tree riêng, leaf trỏ về row qua locator.

37. Khi nào KHÔNG nên tạo index?

Bảng nhỏ, cột thay đổi nhiều, selectivity thấp, bảng heavy write.

38. Composite index — thứ tự cột?

Phải theo left-most prefix. INDEX(A, B, C) dùng được cho A, A+B, A+B+C — không cho B mình hoặc B+C.

39. Covering index?

Index có thêm cột INCLUDE để query không cần seek về bảng:

CREATE INDEX IX ON Orders(CustomerId) INCLUDE (Total, OrderDate);

40. Filtered index?

Chỉ index 1 phần dữ liệu:

CREATE INDEX IX ON Orders(CustomerId) WHERE Status = 'Active';

Nhỏ hơn, nhanh hơn cho query có cùng filter.

41. Sargable nghĩa là gì?

Search-ARGument-able — query mà engine có thể dùng index. Function lên cột → non-sargable → full scan.

42. Vì sao WHERE YEAR(date) = 2026 chậm?

Non-sargable. Sửa: WHERE date >= '2026-01-01' AND date < '2027-01-01'.

43. Key Lookup là gì?

Sau index seek (non-clustered), phải nhảy về clustered lấy thêm cột. Dấu hiệu cần covering index.

44. Fragmentation, rebuild vs reorganize?

  • < 5%: bỏ qua.
  • 5–30%: REORGANIZE (online, nhẹ).
  • 30%: REBUILD (đắt nhưng hết fragment).

G. Transaction & isolation

45. ACID là gì?

Atomicity, Consistency, Isolation, Durability. Giải thích bằng chuyển khoản: trừ A và cộng B phải atomic; balance không âm (consistency); transaction khác không thấy nháp (isolation); commit xong không mất dù crash (durability).

46. Default isolation của SQL Server?

READ COMMITTED (block, không MVCC mặc định). Postgres cùng tên nhưng dùng MVCC.

47. 3 anomaly Isolation chống là gì?

  • Dirty read: đọc data chưa commit.
  • Non-repeatable read: đọc cùng row 2 lần thấy khác.
  • Phantom read: query range 2 lần thấy thêm/bớt row.

48. SNAPSHOT isolation khác READ COMMITTED chỗ nào?

SNAPSHOT dùng MVCC — đọc snapshot tại thời điểm transaction bắt đầu, không block ghi. Bật bằng ALTER DATABASE ... SET ALLOW_SNAPSHOT_ISOLATION ON.

49. NOLOCK hint?

= READ UNCOMMITTED cho 1 query. Cho phép dirty read. Dùng cho báo cáo chấp nhận sai số. Tránh trong nghiệp vụ.

50. Deadlock — tránh thế nào?

Lock cùng thứ tự, giữ transaction ngắn, isolation thấp hơn nếu được. SQL Server tự pick victim rollback.

51. Savepoint?

SAVE TRANSACTION sp1 → có thể rollback về savepoint thay vì toàn transaction.

H. Stored procedure, function, view

52. SP vs Function?

  • SP: thực thi logic, trả nhiều resultset, INSERT/UPDATE/DELETE OK, gọi bằng EXEC.
  • Function: trả 1 giá trị (scalar) hoặc table, dùng được trong SELECT, không SIDE-EFFECT.

53. View và Indexed View?

View = query lưu sẵn, dùng như table. Indexed View (Materialized View của SQL Server) lưu data vật lý → query nhanh nhưng tốn space + maintenance.

54. Trigger các loại?

  • AFTER: sau INSERT/UPDATE/DELETE.
  • INSTEAD OF: thay thế (cho View, làm view ghi được).

Hạn chế: debug khó, logic ẩn → dùng vừa phải.

55. CLR vs T-SQL?

CLR cho phép viết function/procedure bằng C#. Dùng cho logic phức tạp khó express bằng T-SQL (complex math, file I/O). Tuy nhiên, SQL Server 2025 đã có native RegEx (REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR) nên không cần CLR cho regex nữa. Overhead lớn — tránh CLR trong query nóng, ưu tiên T-SQL hoặc batch mode.

I. Performance

56. Vì sao tránh SELECT *?

Lấy cột thừa → băng thông, RAM, phá covering index. Khi bảng thêm cột → query thay đổi hành vi.

57. Parameter sniffing — là gì? Fix sao?

Plan cache dựa parameter lần đầu → lần sau parameter khác có thể tệ. SQL Server 2025 có 2 cơ chế fix tự động:

  • PSPO (Parameter Sensitive Plan Optimization): tự động tạo nhiều plan cho cùng 1 query, chọn plan phù hợp theo parameter runtime.
  • OPPO (Optional Parameter Plan Optimization): tối ưu cho optional parameter.

Cách thủ công: OPTIMIZE FOR UNKNOWN, RECOMPILE, hoặc OPTION (OPTIMIZE FOR (@p = 'typical_value')).

58. Cách điều tra query chậm?

  1. Bật Actual Execution Plan + SET STATISTICS IO ON.
  2. Tìm operator cost cao (Scan, Sort, Hash Match).
  3. Check thiếu index — SSMS gợi ý.
  4. Update statistics.
  5. Kiểm tra parameter sniffing.
  6. Query Store — xem historical plan regression.

59. Khi nào dùng Columnstore index?

Bảng analytics rất lớn, query aggregate. Compress ~10x, query 10–100x nhanh hơn. Không hợp single-row lookup.

60. Partitioning — khi nào cần?

Bảng cực lớn (> 100M row), archive theo thời gian, query luôn filter partition key.

J. SQL Server 2025 — Tổng quan & AI/Vector

61. Có gì mới đáng chú ý ở SQL Server 2025?

SQL Server 2025 (phiên bản 17.x) là bản phát hành AI-native, với những feature lớn sau:

  • Native VECTOR type: lưu và query embedding trong DB, không cần vector DB riêng.
  • DiskANN index: index cho vector search siêu nhanh, tối ưu cho SSD.
  • sp_invoke_external_rest_endpoint: gọi REST API (OpenAI, Azure AI...) từ T-SQL.
  • JSON first-class type: validate tự động, compress tốt hơn, index JSON path.
  • Native RegEx: REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_COUNT, REGEXP_INSTR.
  • PSPO / OPPO: tự động xử lý parameter sniffing, chọn plan tối ưu theo parameter.
  • Optimized Locking: giảm lock memory, tăng concurrency.
  • CE Feedback: Cardinality Estimation feedback — tự học và sửa plan sai.
  • Batch Mode cho built-in functions: STRING_AGG, FIRST_VALUE... chạy batch mode nhanh hơn.
  • TLS 1.3 default, Entra ID (Azure AD) native integration.
  • Real-time CDC sang Azure Event Hubs / Kafka.
  • Express Edition 50GB (tăng từ 10GB).
  • Azure Arc tích hợp sâu cho hybrid management.
2025 là bản "AI-ready" — bạn có thể xây dựng toàn bộ pipeline RAG (Retrieval-Augmented Generation) ngay trong SQL Server mà không cần stack riêng.

62. VECTOR type trong SQL Server 2025 là gì? Dùng như thế nào?

VECTOR(n) là kiểu dữ liệu native để lưu vector embedding — mảng số thực n chiều dùng trong AI/ML. Dùng để semantic search, recommendation, similarity matching ngay trong database, không cần Pinecone/Weaviate/Milvus riêng.

Tạo bảng với VECTOR column:

CREATE TABLE Documents (
    Id INT IDENTITY PRIMARY KEY,
    Title NVARCHAR(500),
    Content NVARCHAR(MAX),
    Embedding VECTOR(1536)  -- OpenAI ada-002 embedding
);

-- Chèn vector
INSERT INTO Documents (Title, Content, Embedding)
VALUES (
    N'Hướng dẫn SQL Server 2025',
    N'SQL Server 2025 có native VECTOR type...',
    CAST('[0.0123, -0.0456, 0.0789, ...]' AS VECTOR(1536))
);

Semantic search — tìm document giống nhất:

DECLARE @queryEmbedding VECTOR(1536) = CAST('[0.01, -0.04, ...]' AS VECTOR(1536));

SELECT TOP 5
    Title,
    VECTOR_DISTANCE('cosine', Embedding, @queryEmbedding) AS Similarity
FROM Documents
ORDER BY Similarity ASC;  -- cosine distance: càng nhỏ càng giống
VECTOR type lưu dưới dạng binary compact — tiết kiệm 50-70% storage so với lưu dạng JSON/string. Kết hợp với DiskANN index, truy vấn hàng triệu vector trong vài ms.

63. DiskANN index hoạt động ra sao? Khác HNSW thế nào?

DiskANN (Disk-based Approximate Nearest Neighbor) là thuật toán vector search do Microsoft Research phát triển, được tích hợp native trong SQL Server 2025.

Tiêu chíDiskANNHNSW (dùng trong pgvector, Weaviate)
Nơi lưu indexDisk (SSD-optimized)RAM (in-memory)
Dung lượngHàng tỷ vector, chỉ cần RAM nhỏBị giới hạn bởi RAM
Build indexNhanh hơn trên dataset lớnChậm hơn khi dataset > 10M
Query latency~1-5ms với SSD NVMe~0.1-1ms (in-memory)
Memory footprintRất thấp (chỉ cache nóng)Cao (toàn bộ graph trong RAM)

Tạo DiskANN index:

CREATE VECTOR INDEX IX_Documents_Embedding
ON Documents (Embedding)
WITH (DISTANCE_METRIC = 'cosine', INDEX_TYPE = 'DISKANN');
DiskANN phù hợp cho production workload — bạn có 100M+ vector, RAM server 32GB vẫn query nhanh vì index nằm trên SSD NVMe. HNSW cần RAM đủ chứa toàn bộ graph, với 100M vector 1536-d → cần ~600GB+ RAM.

64. Làm sao gọi external AI API từ T-SQL? sp_invoke_external_rest_endpoint

SQL Server 2025 giới thiệu sp_invoke_external_rest_endpoint — cho phép gọi bất kỳ REST API nào trực tiếp từ T-SQL. Đây là cầu nối để tích hợp AI/ML, gọi OpenAI, Azure AI, hoặc bất kỳ service nào.

Gọi Azure OpenAI để generate embedding:

DECLARE @response NVARCHAR(MAX);

EXEC sp_invoke_external_rest_endpoint
    @url = 'https://your-openai.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2024-02-01',
    @method = 'POST',
    @headers = '{"api-key": "YOUR_API_KEY", "Content-Type": "application/json"}',
    @payload = N'{"input": "SQL Server 2025 AI features"}',
    @response = @response OUTPUT;

-- Parse embedding từ JSON response (dùng JSON_VALUE với native JSON type)
SELECT JSON_VALUE(@response, '$.data[0].embedding');

Gọi Azure OpenAI Chat Completion ngay trong trigger/procedure:

-- Tự động summarize khi insert document
CREATE PROCEDURE SummarizeDocument
    @content NVARCHAR(MAX),
    @summary NVARCHAR(MAX) OUTPUT
AS
BEGIN
    DECLARE @response NVARCHAR(MAX);
    DECLARE @payload NVARCHAR(MAX) = JSON_OBJECT(
        'messages': JSON_ARRAY(
            JSON_OBJECT('role': 'system', 'content': 'Summarize in Vietnamese in 2 sentences'),
            JSON_OBJECT('role': 'user', 'content': @content)
        ),
        'max_tokens': 200
    );

    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://your-openai.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-01',
        @method = 'POST',
        @headers = '{"api-key": "YOUR_API_KEY"}',
        @payload = @payload,
        @response = @response OUTPUT;

    SET @summary = JSON_VALUE(@response, '$.choices[0].message.content');
END;
sp_invoke_external_rest_endpoint cần enable qua sp_configure 'external rest endpoint enabled', 1. Có thể gọi trong trigger, SP, function — nhưng cẩn thận latency và error handling vì gọi mạng.

65. RAG pattern implement trong SQL Server 2025 như thế nào?

RAG (Retrieval-Augmented Generation) là pattern phổ biến: tìm document liên quan → gửi kèm vào prompt → LLM trả lời chính xác hơn. Với SQL Server 2025, toàn bộ pipeline chạy trong DB:

Kiến trúc RAG trong SQL Server 2025:

User Question → VECTORIZE (sp_invoke_external_rest_endpoint → embedding API)
              → VECTOR SEARCH (VECTOR_DISTANCE + DiskANN index → top K documents)
              → BUILD PROMPT (concat question + retrieved docs)
              → LLM CALL (sp_invoke_external_rest_endpoint → GPT)
              → Response

Implement trong 1 SP:

CREATE PROCEDURE AskRAG
    @question NVARCHAR(MAX),
    @answer NVARCHAR(MAX) OUTPUT
AS
BEGIN
    DECLARE @questionEmbedding VECTOR(1536);
    DECLARE @context NVARCHAR(MAX) = '';
    DECLARE @prompt NVARCHAR(MAX);
    DECLARE @response NVARCHAR(MAX);

    -- Bước 1: Vectorize câu hỏi
    DECLARE @embedResponse NVARCHAR(MAX);
    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://api.openai.com/v1/embeddings',
        @method = 'POST',
        @headers = '{"Authorization": "Bearer YOUR_KEY"}',
        @payload = JSON_OBJECT('input': @question, 'model': 'text-embedding-ada-002'),
        @response = @embedResponse OUTPUT;

    SET @questionEmbedding = CAST(
        JSON_QUERY(@embedResponse, '$.data[0].embedding') AS VECTOR(1536)
    );

    -- Bước 2: Vector search — tìm 5 document gần nhất
    SELECT @context = STRING_AGG(Content, CHAR(10) + CHAR(10))
    FROM (
        SELECT TOP 5 Content
        FROM Documents
        ORDER BY VECTOR_DISTANCE('cosine', Embedding, @questionEmbedding)
    ) AS relevant;

    -- Bước 3: Build prompt với context
    SET @prompt = CONCAT(
        N'Dựa vào các tài liệu sau, trả lời câu hỏi: ',
        CHAR(10), @question, CHAR(10), CHAR(10),
        N'Tài liệu tham khảo:', CHAR(10), @context
    );

    -- Bước 4: Gọi LLM
    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://api.openai.com/v1/chat/completions',
        @method = 'POST',
        @headers = '{"Authorization": "Bearer YOUR_KEY"}',
        @payload = JSON_OBJECT(
            'model': 'gpt-4',
            'messages': JSON_ARRAY(
                JSON_OBJECT('role': 'user', 'content': @prompt)
            )
        ),
        @response = @response OUTPUT;

    SET @answer = JSON_VALUE(@response, '$.choices[0].message.content');
END;
RAG trong DB giúp: (1) không cần microservice riêng, (2) data không rời khỏi DB, (3) dễ audit/security, (4) giảm latency vì không gọi qua nhiều service. Phù hợp enterprise có strict data residency.

66. VECTOR_DISTANCE vs VECTOR_SEARCH — khác nhau thế nào?

VECTOR_DISTANCEVECTOR_SEARCH
Mục đíchTính khoảng cách giữa 2 vector cụ thểTìm top K vector gần nhất
Dùng indexKhông (luôn exact)Có (tận dụng DiskANN index)
Độ chính xác100% (exact search)~95-99% (approximate, tùy cấu hình)
PerformanceTuyến tính O(n) — quét toàn bộO(log n) — dùng index
Use caseSo sánh 2 document cụ thểSearch trong hàng triệu document

VECTOR_DISTANCE — exact comparison:

-- So sánh 2 document xem có giống nhau không
DECLARE @d1 VECTOR(1536), @d2 VECTOR(1536);
SELECT @d1 = Embedding FROM Documents WHERE Id = 1;
SELECT @d2 = Embedding FROM Documents WHERE Id = 2;

SELECT VECTOR_DISTANCE('cosine', @d1, @d2) AS SimilarityScore;
-- Kết quả: 0.0 → 2.0 (cosine): càng gần 0 càng giống

VECTOR_SEARCH — approximate search với index:

DECLARE @queryVec VECTOR(1536) = ...;

SELECT TOP 10
    Id, Title,
    VECTOR_DISTANCE('cosine', Embedding, @queryVec) AS Score
FROM Documents
ORDER BY VECTOR_SEARCH('cosine', Embedding, @queryVec, 'IX_Documents_Embedding')
-- Dùng DiskANN index, nhanh hơn 100-1000x trên dataset lớn
VECTOR_SEARCH dùng index DiskANN → approximate, đủ chính xác cho hầu hết use case AI. Chỉ dùng VECTOR_DISTANCE (exact scan) khi cần chính xác 100% hoặc dataset nhỏ < 10K vector.

67. CREATE EXTERNAL MODEL dùng để làm gì?

CREATE EXTERNAL MODEL tạo reference đến AI/ML model bên ngoài (Azure ML, ONNX, OpenAI deployment) để sử dụng trong T-SQL prediction:

-- Đăng ký Azure OpenAI model
CREATE EXTERNAL MODEL GPT4o_Model
WITH (
    TYPE = 'REST',
    PROVIDER = 'OPENAI',
    URL = 'https://your-openai.openai.azure.com/openai/deployments/gpt-4o',
    AUTHENTICATION = '{"api-key": "YOUR_KEY"}'
);

-- Đăng ký ONNX model cho local inference
CREATE EXTERNAL MODEL SentimentClassifier
WITH (
    TYPE = 'ONNX',
    LOCATION = '/var/opt/mssql/models/sentiment_model.onnx',
    INPUTS = (InputText NVARCHAR(MAX)),
    OUTPUTS = (Label NVARCHAR(50), Probability FLOAT)
);

-- Sử dụng model đã đăng ký
SELECT
    CommentText,
    PREDICT(SentimentClassifier, CommentText) AS Sentiment
FROM Comments;
EXTERNAL MODEL giúp quản lý tập trung model reference, audit trail, và permission. Thay vì hardcode endpoint URL + key trong từng SP, bạn define 1 lần và dùng lại. Thường kết hợp với sp_invoke_external_rest_endpoint cho REST models.

K. SQL Server 2025 — JSON

68. JSON type trong 2025 khác NVARCHAR(MAX) cũ ra sao?

Trước 2025, JSON được lưu dưới dạng NVARCHAR(MAX) + CHECK (ISJSON(col) = 1). SQL Server 2025 giới thiệu native JSON type:

NVARCHAR(MAX) + ISJSONNative JSON (2025)
ValidationManual CHECK ISJSON()Tự động, từ chối JSON sai
StorageUTF-16, không compressBinary format, compress tốt hơn 30-40%
IndexKhông có native JSON indexJSON index trên path
PerformanceParse mỗi lần queryPre-parsed, JSON_VALUE nhanh hơn 2-5x
QueryJSON_VALUE, JSON_QUERYHỗ trợ thêm . dot notation trong path

So sánh cũ vs mới:

-- Cách cũ (pre-2025)
CREATE TABLE OldWay (
    Id INT,
    Data NVARCHAR(MAX),
    CONSTRAINT CK_ValidJSON CHECK (ISJSON(Data) = 1)
);

-- Cách mới (2025)
CREATE TABLE NewWay (
    Id INT,
    Data JSON  -- Native JSON type!
);

-- Dot notation cho path (mới trong 2025)
SELECT Data.name, Data.address.city
FROM NewWay
WHERE Data.age > 25;
Native JSON type lưu dưới dạng binary OSON (Optimized JSON) — Microsoft's internal format. Parse 1 lần khi insert, query sau dùng pre-parsed structure → query JSON_VALUE nhanh hơn hẳn so với string parsing mỗi lần.

69. JSON index trong SQL Server 2025 hoạt động thế nào?

JSON Index giúp tăng tốc query JSON_VALUE trên path cụ thể — giống như index trên cột thông thường nhưng cho JSON:

-- Tạo bảng với JSON type
CREATE TABLE Products (
    Id INT PRIMARY KEY,
    Details JSON
);

-- Tạo JSON index trên các field thường query
CREATE JSON INDEX IX_Product_Category
ON Products (Details)
ON (Details.category, Details.price);

-- Query tận dụng JSON index — seek thay vì scan
SELECT Id, Details.name
FROM Products
WHERE Details.category = N'Điện tử'   -- Dùng index
  AND Details.price < 5000000;         -- Dùng index

Các loại JSON index:

-- Primary JSON index: index mọi path, giống full-text
CREATE JSON INDEX IX_Primary ON Products (Details);

-- Secondary JSON index: index path cụ thể (nhẹ hơn, nhanh hơn)
CREATE JSON INDEX IX_Price ON Products (Details)
ON (Details.price);  -- Chỉ index price path

-- Unique JSON index: đảm bảo unique constraint trên JSON field
CREATE UNIQUE JSON INDEX IX_SKU ON Products (Details)
ON (Details.sku);
Không cần index mọi field JSON — chỉ index những path xuất hiện trong WHERE, JOIN, ORDER BY. Mỗi JSON index tốn storage và làm chậm INSERT/UPDATE. Nên dùng secondary JSON index cho field nóng, tránh primary JSON index trừ khi cần.

70. JSON_ARRAYAGG, JSON_OBJECTAGG, JSON_CONTAINS dùng khi nào?

SQL Server 2025 bổ sung 3 function JSON mạnh mẽ:

JSON_ARRAYAGG — aggregate row thành JSON array:

-- Gộp tất cả sản phẩm của mỗi category thành array
SELECT
    Category,
    JSON_ARRAYAGG(
        JSON_OBJECT('id': Id, 'name': Name, 'price': Price)
        ORDER BY Price DESC
    ) AS ProductsArray
FROM Products
GROUP BY Category;

/*
Kết quả cho Category = 'Điện tử':
[
  {"id": 5, "name": "Laptop", "price": 15000000},
  {"id": 3, "name": "Chuột", "price": 500000}
]
*/

JSON_OBJECTAGG — aggregate key-value thành JSON object:

-- Tạo object với key = ProductId, value = tên sản phẩm
SELECT
    Category,
    JSON_OBJECTAGG(Id, Name) AS ProductMap
FROM Products
GROUP BY Category;

/*
Kết quả:
{"1": "iPhone", "3": "Chuột", "5": "Laptop"}
*/
Trước 2025, phải dùng FOR JSON PATH kết hợp subquery phức tạp. JSON_ARRAYAGGJSON_OBJECTAGG cho phép aggregate trực tiếp trong GROUP BY — code ngắn hơn, dễ đọc hơn nhiều.

JSON_CONTAINS — kiểm tra JSON có chứa value không:

-- Kiểm tra array có chứa giá trị
SELECT *
FROM Orders
WHERE JSON_CONTAINS(Tags, '"VIP"');  -- Tags = ["VIP", "Urgent"]

-- Kiểm tra object có chứa key-value
SELECT *
FROM Products
WHERE JSON_CONTAINS(Details, '{"color": "red"}', '$.attributes');

-- Kiểm tra path tồn tại
SELECT *
FROM Configs
WHERE JSON_CONTAINS(Settings, NULL, '$.features.ai');
-- TRUE nếu Settings có path $.features.ai dù giá trị là gì

71. JSON_MODIFY() có gì mới trong SQL Server 2025?

JSON_MODIFY() trong 2025 hỗ trợ thêm các thao tác nâng cao và performance tốt hơn với native JSON type:

Append vào array:

-- Thêm phần tử vào cuối JSON array
UPDATE Products
SET Details = JSON_MODIFY(Details, 'append $.tags', N'Bestseller');

-- Trước: {"tags": ["New", "Sale"]}
-- Sau:   {"tags": ["New", "Sale", "Bestseller"]}

Delete key khỏi object:

-- Xóa 1 key khỏi JSON object
UPDATE Products
SET Details = JSON_MODIFY(Details, 'delete $.temporaryFlag');

-- Trước: {"name": "Laptop", "temporaryFlag": true, "price": 1000}
-- Sau:   {"name": "Laptop", "price": 1000}

Nested modify (nhiều thay đổi trong 1 call):

-- 2025 hỗ trợ multiple path operations trong 1 JSON_MODIFY
UPDATE Products
SET Details = JSON_MODIFY(
    Details,
    'set $.price', 12000000,
    'set $.discount', 10,
    'append $.tags', N'Khuyến mãi',
    'delete $.old_field'
);
Với native JSON type (thay vì NVARCHAR), JSON_MODIFY không cần re-parse toàn bộ JSON string — chỉ modify pre-parsed binary tree → nhanh hơn 3-5x, đặc biệt trên JSON document lớn.

L. SQL Server 2025 — RegEx

72. REGEXP_LIKE và các function RegEx mới trong T-SQL là gì?

SQL Server 2025 giới thiệu 5 function RegEx native — không cần CLR hay LIKE hack nữa:

FunctionMục đíchVí dụ
REGEXP_LIKEKiểm tra string khớp patternValidate email, phone
REGEXP_REPLACEThay thế theo patternClean data, mask sensitive info
REGEXP_SUBSTRTrích xuất substring theo patternLấy domain từ email
REGEXP_COUNTĐếm số lần pattern xuất hiệnĐếm từ, đếm tag
REGEXP_INSTRTrả về vị trí pattern xuất hiệnTìm vị trí pattern

Ví dụ tổng hợp:

DECLARE @text NVARCHAR(500) = N'Liên hệ: email1@example.com, email2@domain.vn. ĐT: 0912-345-678';

-- REGEXP_LIKE: kiểm tra có email không
SELECT REGEXP_LIKE(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}');
-- TRUE

-- REGEXP_SUBSTR: lấy email đầu tiên
SELECT REGEXP_SUBSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}');
-- 'email1@example.com'

-- REGEXP_REPLACE: mask email thành ***
SELECT REGEXP_REPLACE(
    @text,
    '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}',
    '***@***.***'
);
-- 'Liên hệ: ***@***.***, ***@***.***. ĐT: 0912-345-678'

-- REGEXP_COUNT: đếm số email
SELECT REGEXP_COUNT(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}');
-- 2

-- REGEXP_INSTR: vị trí email đầu tiên
SELECT REGEXP_INSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}');
-- 10 (vị trí bắt đầu của 'email1@example.com')

Validate data với CHECK constraint dùng REGEXP:

CREATE TABLE Users (
    Id INT PRIMARY KEY,
    Email NVARCHAR(256),
    Phone NVARCHAR(20),
    CONSTRAINT CK_ValidEmail
        CHECK (REGEXP_LIKE(Email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')),
    CONSTRAINT CK_ValidPhone
        CHECK (REGEXP_LIKE(Phone, '^0\d{9,10}$'))
);
Pre-2025, RegEx trong SQL Server yêu cầu CLR (C#) hoặc dùng PATINDEX/LIKE hack. Native RegEx 2025: syntax chuẩn POSIX, performance tốt hơn CLR vì chạy trong engine, và được query optimizer hiểu để push-down filter.

73. Khi nào dùng REGEXP vs LIKE? Performance comparison

LIKEREGEXP_LIKE
Pattern đơn giảnLIKE '%abc%', LIKE 'abc_'Hơi overkill
Pattern phức tạpKhông làm được (alternation, repeat, class)Dùng REGEXP
PerformanceIndex seek được nếu prefix cố địnhLuôn scan (hiện tại) trừ khi có full-text
Use caseTìm tên bắt đầu bằng 'Nguyễn'Validate email, phone, extract data
EngineSimple wildcard matchingFull regex engine (POSIX ERE)

Quy tắc chọn:

-- Dùng LIKE: pattern đơn giản, prefix cố định → có thể seek index
SELECT * FROM Customers WHERE Name LIKE N'Nguyễn%';  -- Index seek OK

-- Dùng REGEXP: validate, extract, pattern phức tạp
SELECT * FROM Customers WHERE REGEXP_LIKE(Email, '^[a-z0-9._%+-]+@gmail\.com$');
SELECT REGEXP_REPLACE(Phone, '[^\d]', '') AS CleanPhone FROM Customers;
REGEXP hiện tại không dùng B-tree index (luôn scan). Với bảng lớn, nếu REGEXP pattern có prefix cố định, cân nhắc: WHERE Col LIKE 'prefix%' AND REGEXP_LIKE(Col, 'full_pattern') — LIKE filter trước (index seek), REGEXP refine sau. Hoặc dùng full-text index nếu phù hợp.

74. REGEXP_REPLACE và REGEXP_SUBSTR — use cases thực tế

Clean data hàng loạt:

-- Chuẩn hóa số điện thoại: xóa hết non-digit, thêm +84 nếu bắt đầu bằng 0
UPDATE Customers
SET Phone = REGEXP_REPLACE(
    CASE
        WHEN REGEXP_LIKE(Phone, '^0') THEN '+84' + SUBSTRING(Phone, 2, 20)
        ELSE Phone
    END,
    '[^\d+]',  -- Xóa mọi thứ không phải số hoặc dấu +
    ''
)
WHERE Phone IS NOT NULL;
-- '0912.345.678' → '+84912345678'

Extract structured data từ text tự do:

-- Parse log message: lấy IP, timestamp, status code từ Apache access log
DECLARE @log NVARCHAR(500) = N'192.168.1.1 - - [08/Jul/2026:14:30:00 +0700] "GET /api/products HTTP/1.1" 200 1234';

SELECT
    REGEXP_SUBSTR(@log, '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') AS IP,
    REGEXP_SUBSTR(@log, '\[([^\]]+)\]', 1, 1, 1) AS Timestamp,  -- group 1
    REGEXP_SUBSTR(@log, '"\w+ ([^?]+)') AS Endpoint,            -- path sau method
    REGEXP_SUBSTR(@log, ' (\d{3}) ') AS StatusCode;

Data masking trước khi export:

-- Mask email và credit card trước khi export ra môi trường test
SELECT
    REGEXP_REPLACE(Email, '([^@]+)@', '***@') AS MaskedEmail,
    REGEXP_REPLACE(CreditCard, '\d{12}(\d{4})', '************$1') AS MaskedCC,
    REGEXP_REPLACE(SSN, '\d{3}-\d{2}-(\d{4})', '***-**-$1') AS MaskedSSN
FROM SensitiveData;
REGEXP_REPLACE với capturing group ($1, $2) rất mạnh cho data transformation. Nhớ escape backslash trong SQL string: pattern \d viết thành \\d hoặc dùng N-prefix literal.

M. SQL Server 2025 — Hiệu năng

75. Optimized Locking trong SQL Server 2025 là gì? Tại sao quan trọng?

Optimized Locking là cơ chế quản lý lock mới, giảm đáng kể lock memory và lock escalation. Trước 2025, mỗi row lock tốn ~96 bytes trong lock manager — bảng 10M row update → gần 1GB RAM chỉ cho lock. Optimized Locking giảm xuống còn ~32 bytes/lock bằng cách dùng transaction-local lock hash table.

Cơ chế:

  • Lock được lưu ở row-level trong data page (không ở global lock manager).
  • Chỉ escalate lên global lock manager khi cần cross-transaction conflict.
  • Lock memory tỉ lệ với active lock, không phải total locked rows.
-- Kiểm tra Optimized Locking đã bật chưa
SELECT name, is_optimized_locking_on
FROM sys.databases;

-- Bật Optimized Locking (default ON trong 2025)
ALTER DATABASE MyDB SET OPTIMIZED_LOCKING = ON;
Nếu app của bạn có pattern: xử lý batch lớn (100K+ row update/transaction), Optimized Locking giảm lock memory 60-70% và giảm lock escalation → ít bị blocking chain, tăng concurrency đáng kể.

76. CE Feedback hoạt động ra sao? Khác parameter sniffing cũ thế nào?

Cardinality Estimation (CE) Feedback là cơ chế tự động học và sửa sai của query optimizer. Khi optimizer estimate sai số row → plan xấu → CE Feedback ghi nhận và điều chỉnh model cho lần sau.

Cách hoạt động:

  1. Query chạy → optimizer estimate 100 row, thực tế 10,000 row.
  2. CE Feedback detect discrepancy (estimate vs actual).
  3. Lần sau, optimizer adjust estimate dựa trên history.
  4. Adjustment persist qua restart (lưu trong Query Store).
-- Bật CE Feedback (default ON trong 2025)
ALTER DATABASE SCOPED CONFIGURATION
SET CE_FEEDBACK = ON;

-- Kiểm tra CE Feedback đã apply cho query nào
SELECT
    qt.query_sql_text,
    p.plan_id,
    p.ce_feedback_status,
    p.ce_feedback_last_applied
FROM sys.query_store_plan p
JOIN sys.query_store_query qt ON p.query_id = qt.query_id
WHERE p.ce_feedback_status <> 'None';
Cơ chếParameter Sniffing (cũ)CE Feedback (2025)
Nguyên nhânPlan compile với parameter A, chạy với parameter BEstimate cardinality sai do statistics cũ hoặc complex predicate
FixThủ công (RECOMPILE, hint)Tự động, persist
Scope1 query, 1 parameter setQuery-wide, mọi parameter
PersistKhông (plan recompile thì mất)Có (lưu trong Query Store)
CE Feedback + PSPO = bộ đôi fix tự động 2 nguyên nhân chính gây query chậm. CE Feedback sửa estimate sai, PSPO sửa plan không phù hợp parameter. Cả 2 default ON trong 2025 — giảm 70% ticket "query chạy lúc nhanh lúc chậm".

77. PSPO và OPPO giải quyết vấn đề gì?

Hai cơ chế trong SQL Server 2025 giải quyết parameter sniffing — vấn đề kinh điển khiến plan cache dùng parameter cũ gây query chậm:

PSPO (Parameter Sensitive Plan Optimization): Tự động tạo nhiều plan cho cùng 1 query, mỗi plan tối ưu cho 1 range parameter khác nhau. Runtime, engine chọn plan phù hợp dựa trên giá trị thực của parameter.

-- Bật PSPO
ALTER DATABASE SCOPED CONFIGURATION
SET PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = ON;

-- Ví dụ: query này có 2 plan:
-- Plan A: @Status = 'Active' (80% rows → scan clustered)
-- Plan B: @Status = 'Pending' (0.1% rows → index seek + key lookup)
SELECT * FROM Orders WHERE Status = @Status;
-- PSPO tự tạo cả 2 plan, runtime chọn dựa trên @Status thực tế

OPPO (Optional Parameter Plan Optimization): Tối ưu cho query có optional parameter (NULL = "lấy tất cả"):

-- Query có optional parameter
CREATE PROCEDURE SearchOrders
    @CustomerId INT = NULL,     -- NULL = tất cả khách
    @Status NVARCHAR(20) = NULL -- NULL = tất cả trạng thái
AS
BEGIN
    SELECT * FROM Orders
    WHERE (@CustomerId IS NULL OR CustomerId = @CustomerId)
      AND (@Status IS NULL OR Status = @Status);
END;

-- OPPO tự detect và optimize dạng query này,
-- thay vì 1 plan xấu cho mọi combination
-- Bật OPPO
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIONAL_PARAMETER_PLAN_OPTIMIZATION = ON;
Phân biệt nhanh: PSPO = nhiều plan cho cùng query dựa trên parameter selectivity. OPPO = optimize query có @p IS NULL OR col = @p pattern. Cả 2 đều là adaptive optimization, không cần RECOMPILE hint.

78. Batch Mode cho built-in functions — hiệu suất tăng bao nhiêu?

SQL Server 2025 mở rộng Batch Mode on Rowstore — cho phép một số built-in functions chạy dưới dạng batch processing (xử lý 900 row/lô) thay vì row-by-row:

Function được hưởng lợi:

  • STRING_AGG
  • FIRST_VALUE, LAST_VALUE
  • LAG, LEAD
  • PERCENTILE_CONT, PERCENTILE_DISC
  • APPROX_PERCENTILE_CONT, APPROX_PERCENTILE_DISC
  • ROW_NUMBER, RANK, DENSE_RANK, NTILE

Performance impact (theo Microsoft benchmark):

OperationRow ModeBatch Mode (2025)Speedup
STRING_AGG (10M rows)45s8s5.6x
Window functions (10M rows)120s18s6.7x
PERCENTILE_CONT (50M rows)380s42s9x
-- Batch mode tự động kích hoạt với compatible level 170 (2025)
ALTER DATABASE MyDB SET COMPATIBILITY_LEVEL = 170;

-- Kiểm tra execution plan: tìm operator "Batch Hash Aggregate"
-- hoặc "Batch Window Aggregate" thay vì row-mode tương ứng

-- Ép buộc row mode (để compare)
SELECT Category, STRING_AGG(Name, ', ')
FROM Products
GROUP BY Category
OPTION (USE HINT('DISALLOW_BATCH_MODE'));
Batch Mode trên Rowstore là game-changer cho ETL/analytics query — không cần Columnstore index, không cần thay đổi schema. Chỉ cần nâng compatibility level lên 170. Query có window function hoặc STRING_AGG chạy trên bảng > 1M row sẽ thấy khác biệt rõ nhất.

N. SQL Server 2025 — Edition, Cloud & Hybrid

79. Express Edition 2025 có gì mới?

SQL Server 2025 Express Edition có thay đổi lớn nhất trong lịch sử Express:

Tính năngExpress 2019/2022Express 2025
Max database size10 GB50 GB
RAM sử dụng~1.4 GB~2 GB (buffer pool)
CPU1 socket / 4 cores1 socket / 4 cores
VECTOR typeKhông có
Native JSONKhông có
Native RegExKhông có
DiskANN indexKhông cóCó (giới hạn)
TLS 1.3Không
# Pull và chạy SQL Server 2025 Express trên Docker
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_EDITION=Express" \
  -p 1433:1433 \
  mcr.microsoft.com/mssql/server:2025-latest
50GB thay đổi hoàn toàn game: Express giờ có thể chạy production cho phần lớn SME app, blog, e-commerce nhỏ, internal tool. Kết hợp với AI feature (VECTOR, JSON native), Express 2025 là lựa chọn cực mạnh để build proof-of-concept RAG/AI app mà không tốn license.

80. SQL Server on Linux 2025 khác Windows ở đâu?

SQL Server 2025 on Linux đạt near-complete feature parity với Windows:

FeatureWindows 2025Linux 2025
Engine (VECTOR, JSON, RegEx, DiskANN)
Always On Availability Groups✅ (Pacemaker)
Machine Learning Services
Active Directory Auth✅ (Kerberos)
sp_invoke_external_rest_endpoint
SSIS / SSRS / SSAS
FileTable / FileStream
Stretch Database
Kubernetes OperatorKhông cần✅ (native)
Container / PodmanOK✅ Tối ưu

Linux-specific advantages:

# Triển khai trên K8s với SQL Server Operator 2025
kubectl apply -f sqlserver-2025-operator.yaml

# Tự động failover, backup, scale
kubectl get sqlservers
Nếu stack của bạn là: .NET backend + SQL Server + Docker/K8s → deploy toàn bộ lên Linux. Feature không có (SSIS, SSRS) thường đã được thay thế bởi Azure Data Factory + Power BI cloud. Linux container image SQL 2025 nhẹ hơn Windows image ~40%.

81. Azure Arc cho SQL Server 2025 mang lại lợi ích gì?

Azure Arc là bridge giữa on-premise SQL Server và Azure cloud — quản lý SQL Server anywhere (on-prem, edge, other cloud) từ Azure portal:

-- Connect SQL Server 2025 vào Azure Arc
-- (chạy trên máy on-premise)
EXEC sys.arc_connect
    @tenant_id = 'your-tenant-id',
    @subscription_id = 'your-subscription-id',
    @resource_group = 'sql-servers-rg';

Lợi ích chính:

Tính năngMô tả
Azure Update ManagerPatch SQL Server tự động, lên lịch, theo policy
Microsoft Defender for SQLPhát hiện SQL injection, anomaly, vulnerability assessment
Microsoft PurviewData catalog, classification, lineage — scan on-prem data
Best Practice AssessmentCheck config SQL Server theo best practice Microsoft
Centralized MonitoringTất cả SQL instance (on-prem + cloud) trong 1 dashboard
Billing flexibilityPay-as-you-go license qua Azure, không cần SA contract
Failover to AzureDR site là Azure SQL Managed Instance — Arc tự động failover

::callout{icon="i-lucide-star" color="warning"> Azure Arc đặc biệt hữu ích cho doanh nghiệp có SQL Server on-prem + hybrid. Thay vì quản lý từng server riêng lẻ, toàn bộ fleet được manage từ Azure portal: patch, security audit, compliance — tất cả tập trung. Free cho management, pay cho advanced security feature. ::

P. SQL on Linux, Azure Hybrid & Fabric

86. SQL Server on Linux khác Windows ở điểm nào?

Tiêu chíWindowsLinux
Process modelSQL Server service chạy trong Windows kernelChạy như process Linux thông thường
AuthenticationWindows Auth + SQL AuthChỉ SQL Auth (không có AD native — dùng Kerberos/PAM hoặc Azure Arc để bắc cầu)
File systemNTFS, ReFSEXT4, XFS
TempDBFile trên diskCó thể dùng tmpfs (RAM disk) — nhanh hơn nhiều
SQL Server AgentService riêng, bật mặc địnhTắt mặc định, bật bằng mssql-conf
High AvailabilityAlways On AG, FCI với WSFCAG với Pacemaker (RHEL/Ubuntu), không có FCI
PerformanceTối ưu Windows kernelGần tương đương (2022+: < 5% khác biệt)
ContainerDocker Windows container (lớn, ít dùng)Docker Linux container (40% nhỏ hơn, nhanh hơn)
SSIS/SSAS/SSRSCó đầy đủKhông hỗ trợ (chỉ có Database Engine)
Container Linux là default recommendation 2026: image nhẹ hơn (1.5GB vs 6GB), start nhanh hơn, dễ CI/CD. Production on-prem vẫn ưu tiên Windows nếu cần full stack (SSIS/SSAS/SSRS). Cloud thì Azure SQL hoặc Azure VM với SQL Linux đều OK.

87. Azure Arc-enabled SQL Server là gì? Lợi ích?

Azure Arc = bridge kết nối SQL Server on-prem (hoặc cloud khác) vào Azure control plane:

┌─────────────────────────────────────────────────┐
│                  Azure Portal                     │
│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│  │ Security │ │  Update  │ │ Compliance        │ │
│  │ Center   │ │ Manager  │ │ (Microsoft Purview)│ │
│  └────┬─────┘ └────┬─────┘ └────────┬─────────┘ │
└───────┼────────────┼───────────────┼────────────┘
        │            │               │
   ┌────▼────────────▼───────────────▼────────────┐
   │         Azure Arc agent (on-prem)             │
   │  ┌──────────┐  ┌─────────────┐               │
   │  │ SQL Svr 1│  │ SQL Svr 2   │  ...          │
   │  │ (Windows)│  │ (Linux)     │               │
   │  └──────────┘  └─────────────┘               │
   └──────────────────────────────────────────────┘

Lợi ích cụ thể:

Tính năngChi tiết
Unified managementQuản lý toàn bộ fleet SQL Server (on-prem + cloud) từ 1 Azure portal
Microsoft Entra ID authDùng Entra ID (Azure AD cũ) để đăng nhập SQL Server on-prem — không cần Windows AD
Automated updatesPatch SQL Server tự động theo schedule, giống Windows Update
Security complianceMicrosoft Purview đánh giá security posture, phát hiện misconfiguration
Best practices assessmentTự động scan instance, so sánh với best practice, report gap
Cost managementNếu có Software Assurance, Azure Arc SQL được giảm đến 20% Azure cost khi migrate lên cloud sau này
Khi nào đầu tư Azure Arc? Doanh nghiệp có > 10 SQL Server instance on-prem, muốn centralized management + security compliance. Đặc biệt hữu ích khi hybrid strategy: 1 phần workload đã migrate Azure, phần còn lại vẫn on-prem.

88. Azure SQL Hyperscale — khi nào chọn thay vì SQL Server on-prem?

Yếu tốSQL Server on-premAzure SQL Hyperscale
Dung lượngMax ~524PB (lý thuyết), thực tế vài TBLên đến 100TB (auto-grow, không cần filegroup planning)
Scale computeScale-up (thêm CPU/RAM) mất downtimeScale-up/down online, vài giây
Scale readsAG secondary, max 8 replica0-30 named replicas, tạo trong < 1 phút
Failover30s-2 phút (AG failover)< 10 giây
Backup/RestoreThủ công (maintenance plan, agent job)Snapshot backup < 10 phút cho DB bất kỳ kích thước (kể cả 100TB)
RCSI / SnapshotPhải bật thủ côngBật mặc định
LicensingLicense + SA hoặc pay-as-you-goPay-as-you-go hoặc reserved instance (tiết kiệm ~35%)
Enterprise featureĐầy đủ (AG, partitioning, SSIS...)Một số feature không có (SSIS, SSAS, Agent job hạn chế một số thứ)
Hyperscale snapshot restore: restore database 100TB trong < 10 phút — là killer feature. SQL Server on-prem restore 10TB có thể mất 10+ giờ. Cơ chế: page server dùng storage snapshot thay vì copy data.

89. SQL Database trong Microsoft Fabric — dùng khi nào?

-- Không cần CREATE SERVER, chỉ cần CREATE DATABASE
CREATE DATABASE SalesAnalytics;
GO

USE SalesAnalytics;
CREATE TABLE orders (...);
-- Dùng T-SQL y hệt, có VECTOR, JSON, RegEx đầy đủ

Khác biệt chính với Azure SQL Database truyền thống:

Azure SQL DatabaseFabric SQL Database
ProvisionCần tạo logical server → tạo DBCREATE DATABASEserverless hoàn toàn
BillingTheo vCore/DTU + storageTheo dung lượng data + compute dùng thực tế trong Fabric capacity
CopilotQua SSMS 22Tích hợp sẵn trong Fabric portal (NL → SQL, tự động suggest)
EcosystemĐộc lập, connect từ app ngoàiTích hợp OneLake, Power BI direct query, notebook, data pipeline
Scale giới hạnHyperscale 100TBFabric capacity giới hạn (tuỳ SKU)
Use caseProduction OLTP appAnalytics, reporting, data warehouse nhỏ, team muốn SQL mà không muốn DevOps
Fabric SQL không thay thế Azure SQL Database. Fabric SQL = SQL cho analytics team (dữ liệu đã ở Fabric). Azure SQL Database = SQL cho production application (OLTP, REST API, high concurrency).

90. Làm sao kết nối SQL Server on-prem với Azure services mà không expose ra internet?

# Azure Arc: cài agent lên SQL Server on-prem
# Agent chỉ cần OUTBOUND HTTPS (443) → không cần mở inbound port

# 1. Tạo Azure Arc resource trong portal
az connectedmachine create --resource-group my-rg \
    --name sql-onprem-01 --location westeurope

# 2. Cài Azure Connected Machine agent lên server on-prem
# (download script từ Azure portal)

# 3. Enable SQL Server extension
az connectedmachine extension create \
    --machine-name sql-onprem-01 \
    --name WindowsAgent.SqlServer \
    --type WindowsAgent.SqlServer

# 4. SQL Server xuất hiện trong Azure portal → quản lý như cloud resource
# Dùng Entra ID để auth: không cần Windows AD!
Security note: Azure Arc agent dùng outbound-only connection (HTTPS 443) → không cần mở firewall inbound. Phù hợp với chính sách bảo mật doanh nghiệp. Data (query result, row data) không gửi lên Azure — chỉ metadata (instance name, version, config, health status).

O. Câu trick & scenario

82. Cho 1 bảng 100M row, query WHERE Status = 'Active' chậm. Tìm nguyên nhân?

Bước:

  1. Check có index trên Status không.
  2. Check selectivity: nếu 80% row là Active → index vô dụng, phải scan.
  3. Tạo filtered index WHERE Status = 'Active' nếu cần.
  4. Hoặc partition theo Status.

83. Migration đổi cột INTBIGINT trên bảng 1 tỷ row, không downtime?

  • Tạo cột mới BIGINT NULL, default NULL.
  • Backfill batch theo PK range (1000 row/batch), tránh long lock.
  • Sau khi backfill xong: trigger duplicate ghi trong transition.
  • Đổi index, FK trỏ sang cột mới.
  • Drop cột cũ.

84. Server slow, RAM đầy, CPU cao — bạn check gì đầu tiên?

  • sys.dm_exec_query_stats — top query theo CPU/IO.
  • sys.dm_os_wait_stats — wait type chính (PAGEIOLATCH = thiếu RAM, CXPACKET = parallelism).
  • sys.dm_db_index_usage_stats — index dùng nhiều ít.
  • Check Query Store nếu đã bật.

85. Block với Deadlock khác gì?

  • Block: 1 transaction đợi lock từ transaction khác — sẽ tiếp tục khi giải phóng.
  • Deadlock: 2 transaction đợi lock của nhau vô tận → engine kill 1.

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.