Truy vấn T-SQL nâng cao
1. JOIN — đào sâu
5 loại JOIN + minh hoạ
-- INNER — chỉ row match cả 2 bảng
SELECT c.Name, o.OrderDate
FROM Customers c
INNER JOIN Orders o ON o.CustomerId = c.Id;
-- LEFT — tất cả customer + đơn nếu có
SELECT c.Name, o.OrderDate
FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.Id;
-- RIGHT — đảo lại (ít dùng vì khó đọc, swap LEFT thuận hơn)
SELECT c.Name, o.OrderDate
FROM Orders o
RIGHT JOIN Customers c ON o.CustomerId = c.Id;
-- FULL OUTER — tất cả row 2 bên
SELECT c.Name, o.OrderDate
FROM Customers c
FULL OUTER JOIN Orders o ON o.CustomerId = c.Id;
-- CROSS — tích Descartes (m × n)
SELECT c.Name, p.Name
FROM Customers c CROSS JOIN Products p;
ON, không phải WHERE, để giữ NULL.-- ❌ Vô tình biến LEFT JOIN thành INNER
SELECT c.* FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.Id
WHERE o.Status = 'Paid'; -- lọc luôn row có o.Status NULL
-- ✅ Đặt vào ON
SELECT c.* FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.Id AND o.Status = 'Paid';
SELF JOIN
-- Bảng Employees có ManagerId trỏ về Employees.Id
SELECT e.Name AS Employee, m.Name AS Manager
FROM Employees e
LEFT JOIN Employees m ON m.Id = e.ManagerId;
Anti-join — tìm record KHÔNG có liên kết
-- Khách hàng chưa từng đặt đơn — 3 cách
-- 1. LEFT JOIN ... IS NULL
SELECT c.* FROM Customers c
LEFT JOIN Orders o ON o.CustomerId = c.Id
WHERE o.Id IS NULL;
-- 2. NOT EXISTS (thường tốt nhất với SQL Server)
SELECT c.* FROM Customers c
WHERE NOT EXISTS (
SELECT 1 FROM Orders o WHERE o.CustomerId = c.Id
);
-- 3. NOT IN (cẩn thận NULL!)
SELECT c.* FROM Customers c
WHERE c.Id NOT IN (
SELECT CustomerId FROM Orders WHERE CustomerId IS NOT NULL
);
NOT INcho kết quả sai nếu subquery có NULL (vìx <> NULLlà UNKNOWN).NOT EXISTSxử lý NULL đúng + thường có plan tốt hơn.- Khuyến nghị: mặc định dùng
NOT EXISTS.
2. Subquery
Scalar subquery — trả 1 giá trị
SELECT Name,
(SELECT COUNT(*) FROM Orders WHERE CustomerId = c.Id) AS OrderCount
FROM Customers c;
Correlated subquery — tham chiếu outer query
-- Top 3 sản phẩm đắt nhất MỖI category
SELECT * FROM Products p1
WHERE (
SELECT COUNT(*) FROM Products p2
WHERE p2.CategoryId = p1.CategoryId AND p2.Price > p1.Price
) < 3;
→ Cách hiện đại: dùng Window function (mục 5).
EXISTS
-- Khách có ít nhất 1 đơn > 10 triệu
SELECT * FROM Customers c
WHERE EXISTS (
SELECT 1 FROM Orders o
WHERE o.CustomerId = c.Id AND o.Total > 10000000
);
Derived table (inline view)
SELECT t.City, t.TotalRevenue
FROM (
SELECT c.City, SUM(o.Total) AS TotalRevenue
FROM Customers c JOIN Orders o ON o.CustomerId = c.Id
GROUP BY c.City
) t
WHERE t.TotalRevenue > 100000000;
3. Set operations
-- UNION — gộp + loại trùng (chậm hơn)
SELECT Email FROM Customers
UNION
SELECT Email FROM Suppliers;
-- UNION ALL — gộp, không loại trùng (NHANH HƠN)
SELECT Email FROM Customers
UNION ALL
SELECT Email FROM Suppliers;
-- INTERSECT — giao
SELECT Email FROM Customers
INTERSECT
SELECT Email FROM Suppliers;
-- EXCEPT — hiệu (A trừ B)
SELECT Email FROM Customers
EXCEPT
SELECT Email FROM Suppliers;
UNION vs UNION ALL:UNION thêm bước SORT DISTINCT (tốn). Nếu biết chắc không trùng, dùng UNION ALL nhanh hơn nhiều.4. CTE — Common Table Expression
CTE đơn giản
WITH HighValueOrders AS (
SELECT * FROM Orders WHERE Total > 10000000
)
SELECT c.Name, COUNT(*) AS BigOrderCount
FROM HighValueOrders o
JOIN Customers c ON c.Id = o.CustomerId
GROUP BY c.Name;
CTE giúp code đọc dễ hơn nhiều subquery lồng nhau.
CTE đa stage
WITH
TopCustomers AS (
SELECT TOP 10 CustomerId, SUM(Total) AS Spent
FROM Orders GROUP BY CustomerId
ORDER BY Spent DESC
),
TheirOrders AS (
SELECT o.* FROM Orders o
WHERE o.CustomerId IN (SELECT CustomerId FROM TopCustomers)
)
SELECT * FROM TheirOrders WHERE OrderDate >= '2026-01-01';
Recursive CTE — tree
-- Build cây tổ chức từ root xuống
WITH OrgTree AS (
-- Anchor: root (không có manager)
SELECT Id, Name, ManagerId, 0 AS Lvl, CAST(Name AS NVARCHAR(MAX)) AS Path
FROM Employees WHERE ManagerId IS NULL
UNION ALL
-- Recursive: tìm nhân viên có manager đã ở trong tree
SELECT e.Id, e.Name, e.ManagerId, t.Lvl + 1,
CAST(t.Path + N' > ' + e.Name AS NVARCHAR(MAX))
FROM Employees e
JOIN OrgTree t ON t.Id = e.ManagerId
)
SELECT * FROM OrgTree ORDER BY Path;
5. Window function
Cấu trúc tổng quát
function_name() OVER (
[PARTITION BY col1, col2 ...]
[ORDER BY col1 [ASC|DESC] ...]
[ROWS|RANGE BETWEEN ... AND ...]
)
Ranking — ROW_NUMBER / RANK / DENSE_RANK
-- Cùng dữ liệu: 100, 100, 90, 80
SELECT
Value,
ROW_NUMBER() OVER (ORDER BY Value DESC) AS Rn, -- 1, 2, 3, 4
RANK() OVER (ORDER BY Value DESC) AS Rk, -- 1, 1, 3, 4 (skip)
DENSE_RANK() OVER (ORDER BY Value DESC) AS Dk -- 1, 1, 2, 3 (no skip)
FROM Scores;
Use case kinh điển — Top N per group
-- Đơn hàng MỚI NHẤT của MỖI khách
WITH Ranked AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY CustomerId
ORDER BY OrderDate DESC
) AS Rn
FROM Orders
)
SELECT * FROM Ranked WHERE Rn = 1;
Aggregate window function
SELECT
OrderDate,
Total,
SUM(Total) OVER (ORDER BY OrderDate) AS RunningTotal,
AVG(Total) OVER (
ORDER BY OrderDate
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS MovingAvg7Days
FROM Orders;
LAG / LEAD — so sánh row liền kề
SELECT
OrderDate, Total,
LAG(Total) OVER (ORDER BY OrderDate) AS PrevTotal,
Total - LAG(Total) OVER (ORDER BY OrderDate) AS DeltaFromPrev
FROM Orders;
NTILE — chia bucket
-- Chia khách thành 4 quartile theo total spend
SELECT CustomerId, Spent,
NTILE(4) OVER (ORDER BY Spent DESC) AS Quartile
FROM (
SELECT CustomerId, SUM(Total) AS Spent
FROM Orders GROUP BY CustomerId
) t;
6. Aggregate & GROUP BY nâng cao
GROUPING SETS / ROLLUP / CUBE
-- Tổng theo nhiều combination cùng lúc — báo cáo
SELECT City, Status, COUNT(*) AS Cnt
FROM Orders o JOIN Customers c ON c.Id = o.CustomerId
GROUP BY GROUPING SETS (
(City, Status), -- detail
(City), -- subtotal theo City
(Status), -- subtotal theo Status
() -- grand total
);
-- ROLLUP = subtotal lũy tiến
GROUP BY ROLLUP (Year, Month, Day);
-- CUBE = mọi combination
GROUP BY CUBE (City, Status);
HAVING vs WHERE
-- WHERE lọc TRƯỚC group, HAVING lọc SAU group
SELECT City, COUNT(*) cnt
FROM Customers
WHERE IsActive = 1 -- trước group
GROUP BY City
HAVING COUNT(*) > 5; -- sau group
STRING_AGG (2017+)
-- Gộp tên người trong cùng city thành 1 string
SELECT City, STRING_AGG(Name, ', ')
WITHIN GROUP (ORDER BY Name) AS People
FROM Customers
GROUP BY City;
7. PIVOT / UNPIVOT
-- Doanh thu theo tháng, hàng = sản phẩm
SELECT *
FROM (
SELECT ProductName, MONTH(OrderDate) AS m, Total
FROM Orders
) src
PIVOT (
SUM(Total) FOR m IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS p;
PIVOT hay được dùng cho báo cáo. Với data dynamic cột → kết hợp dynamic SQL.
8. Transaction & ACID
Cú pháp transaction
BEGIN TRANSACTION;
BEGIN TRY
UPDATE Accounts SET Balance = Balance - 1000 WHERE Id = 1;
UPDATE Accounts SET Balance = Balance + 1000 WHERE Id = 2;
IF (SELECT Balance FROM Accounts WHERE Id = 1) < 0
THROW 50001, N'Insufficient funds', 1;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW; -- rethrow để app biết
END CATCH
Savepoint
BEGIN TRANSACTION;
INSERT INTO Logs VALUES ('Step 1');
SAVE TRANSACTION sp1;
INSERT INTO Logs VALUES ('Step 2');
IF (@@ERROR <> 0) ROLLBACK TRANSACTION sp1; -- rollback về step 1 thôi
COMMIT TRANSACTION;
ACID — định nghĩa
| Ý nghĩa | |
|---|---|
| Atomicity | Tất cả hoặc không gì — commit hết hoặc rollback hết. |
| Consistency | DB trước-sau transaction vẫn hợp lệ (PK, FK, CHECK). |
| Isolation | Transaction không thấy nháp của transaction khác. |
| Durability | Sau COMMIT, dữ liệu bền vững dù crash. |
9. Isolation level
5 level của SQL Server
| Level | Dirty read | Non-repeatable read | Phantom read |
|---|---|---|---|
| Read Uncommitted | ✅ Có | ✅ Có | ✅ Có |
| Read Committed (default) | ❌ | ✅ | ✅ |
| Repeatable Read | ❌ | ❌ | ✅ |
| Serializable | ❌ | ❌ | ❌ |
| Snapshot | ❌ | ❌ | ❌ (dùng MVCC versioning) |
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- ...transaction body...
-- Hoặc per query (hint)
SELECT * FROM Orders WITH (NOLOCK); -- = READ UNCOMMITTED — dirty read OK
3 anomaly cần thuộc
- Dirty read: đọc dữ liệu của transaction CHƯA commit.
- Non-repeatable read: đọc cùng row 2 lần, lần 2 thấy khác (vì transaction khác UPDATE+commit giữa chừng).
- Phantom read: query 1 range 2 lần, lần 2 thấy thêm/bớt row (vì transaction khác INSERT/DELETE).
- SQL Server: READ COMMITTED (block, không MVCC mặc định).
- Postgres: READ COMMITTED nhưng dùng MVCC — đọc không block ghi.
- MySQL InnoDB: REPEATABLE READ (default cao hơn 2 cái trên).
NOLOCK — đừng lạm dụng
WITH (NOLOCK) = READ UNCOMMITTED cho 1 query. Dùng cho báo cáo chấp nhận sai số nhẹ. Tránh trong code nghiệp vụ (ngân hàng, đơn hàng) — gây dirty read.
10. Deadlock — nhận biết & tránh
- Lock theo cùng thứ tự trong mọi transaction (vd: luôn UPDATE Account A trước B).
- Giữ transaction ngắn.
- Update đúng cột cần, không lock thừa.
- Isolation thấp hơn nếu được (Snapshot).
-- Bật theo dõi deadlock trong session
DBCC TRACEON (1222, -1); -- log deadlock graph ra ERRORLOG
11. AI-Augmented Query Optimization (SQL Server 2025)
SQL Server 2025 dua AI/ML vao query optimizer -- engine tu hoc tu workload thuc te de chon plan tot hon.
Cardinality Estimation (CE) Feedback
-- Bat CE Feedback (mac dinh ON trong 2025)
ALTER DATABASE SCOPED CONFIGURATION
SET CE_FEEDBACK = ON;
-- Kiem tra feedback da duoc ap dung
SELECT * FROM sys.query_store_plan_feedback
WHERE feature_id = 1; -- CE feedback
- Bad parameter sniffing -- khi plan duoc compile cho tham so A nhung chay voi tham so B gay scan ca bang.
- CE Feedback phat hien sai, tu tao plan moi -- khong can RECOMPILE hint hay plan guide thu cong.
- Khac voi Query Store plan forcing: CE Feedback tu dong va hoc lien tuc.
PSPO -- Parameter Sensitive Plan Optimization
-- Bat PSPO (mac dinh ON trong 2025)
ALTER DATABASE SCOPED CONFIGURATION
SET PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = ON;
PSPO cache nhieu execution plan cho cung 1 query, moi plan toi uu cho 1 khoang gia tri tham so khac nhau. Khi chay, engine tu chon plan phu hop nhat voi gia tri hien tai.
@Status -- khi @Status = 'Active' tra 90% bang, khi @Status = 'Suspended' tra 0.1% bang. PSPO giu 2 plan rieng, khong con "1 plan fit all" gay loi.OPPO -- Optional Parameter Plan Optimization
Giai quyet van de optional parameter -- khi tham so co the NULL hoac co gia tri:
-- Pattern pho bien gay van de:
SELECT * FROM Orders
WHERE (@CustomerId IS NULL OR CustomerId = @CustomerId)
AND (@Status IS NULL OR Status = @Status);
-- ⚠️ OPTION (RECOMPILE) truoc day la cach chua duy nhat
OPPO tu dong nhan dien pattern nay, tao plan toi uu cho tung to hop tham so, khong can OPTION (RECOMPILE).
Optimized Locking -- dot pha ve concurrency
-- Bat Optimized Locking (mac dinh ON trong 2025)
ALTER DATABASE SCOPED CONFIGURATION
SET OPTIMIZED_LOCKING = ON;
| Truoc 2025 | Tu 2025 |
|---|---|
| UPDATE 10,000 rows → escalate len page/table lock | UPDATE 10,000 rows → giu 10,000 row-level locks |
| Chan toan bo session khac | Session khac van truy cap rows khac binh thuong |
LAQ -- Lock After Qualification
-- Pattern duoc LAQ toi uu:
UPDATE Orders SET Status = 'Processed'
WHERE Status = 'Pending' AND OrderDate < '2026-01-01';
| Truoc 2025 | Voi LAQ |
|---|---|
| Lock TAT CA rows trong bang → loc WHERE → update rows match | Loc WHERE truoc → chi lock rows match dieu kien |
12. Batch Mode cho Built-in Functions (SQL Server 2025)
Cac ham built-in nay gio chay o batch mode (vectorized) thay vi row-by-row:
ABS(),SIN(),COS(),DATE_TRUNC(),LOG(),EXP(),SQRT(),POWER(),CEILING(),FLOOR(),ROUND(),GREATEST(),LEAST()
-- Query nay gio chay ~70% nhanh hon nho batch mode
SELECT
ABS(PriceChange) AS AbsoluteChange,
SIN(RADIANS(Latitude)) AS SinLat,
DATE_TRUNC('month', OrderDate) AS OrderMonth
FROM Orders
WHERE OrderDate >= '2026-01-01';
- Batch mode xu ly 900 rows/lan (vectorized), thay vi tung row mot (row mode).
- Truoc 2025: chi columnstore indexes, aggregate functions (SUM, AVG) va mot vai operator dung batch mode.
- 2025: mo rong sang built-in scalar functions -- CPU-bound queries cai thien ~70%.
- Khong can thay doi code -- optimizer tu chon batch mode khi co loi.
13. OPTIMIZED_SP_EXECUTESQL (SQL Server 2025)
-- Thay vi sp_executesql thong thuong
EXEC sp_executesql @sql, @params, @p1, @p2;
-- Dung OPTIMIZED variant
EXEC sys.OPTIMIZED_SP_EXECUTESQL @sql, @params, @p1, @p2;
Van de: Khi nhieu connection cung goi 1 stored procedure lan dau tien, moi connection deu co gang compile rieng → "compile storm" ton CPU, tranh Plan Cache.
Giai phap: OPTIMIZED_SP_EXECUTESQL chia se cung 1 compiled plan cho tat ca cac concurrent executions, chi compile 1 lan duy nhat.
14. Vector Search trong Truy van
SQL Server 2025 ho tro native vector operations cho semantic/embedding search.
Semantic search ket hop SQL truyen thong
-- Tim 10 san pham tuong tu nhat, kem loc theo category + gia
DECLARE @query_vector VECTOR(1536);
-- @query_vector duoc tao tu embedding model (OpenAI, v.v.)
SELECT TOP 10
p.name,
p.price,
VECTOR_DISTANCE('cosine', p.embedding, @query_vector) AS score
FROM products p
WHERE p.category_id = 5
AND p.price BETWEEN 100 AND 1000
ORDER BY score ASC;
Hybrid search: filter + vector
-- Dung VECTOR_SEARCH de lay tap ung vien, sau do JOIN loc them
WITH semantic AS (
SELECT
id,
VECTOR_DISTANCE('cosine', embedding, @query_vector) AS score
FROM products
WHERE VECTOR_SEARCH(embedding, @query_vector, 100)
)
SELECT p.*, s.score
FROM products p
JOIN semantic s ON p.id = s.id
WHERE p.in_stock = 1
ORDER BY s.score ASC;
- Hybrid search = vector similarity + traditional SQL filter (WHERE, JOIN, GROUP BY).
- Chi dung vector: tim "giay chay bo" tra ve ca san pham het hang hoac sai category.
- Hybrid: semantic similarity trong pham vi category="shoes" AND in_stock=1.
- Pattern: CTE/WITH de tinh vector score → JOIN ra bang goc → loc them.
Tao & quan ly vector index
-- Tao vector index cho tim kiem ANN (Approximate Nearest Neighbor)
CREATE VECTOR INDEX idx_product_embedding
ON products (embedding)
WITH (DISTANCE_METRIC = 'cosine', INDEX_TYPE = 'IVFFLAT');
-- Query su dung index
SELECT TOP 20 name, VECTOR_DISTANCE('cosine', embedding, @query_vector) AS score
FROM products
ORDER BY score ASC;
cosine (pho bien nhat cho semantic similarity), euclidean, dot_product. Chon tuy theo embedding model cua ban.15. JSON Queries Nang Cao
SQL Server 2025 bo sung cac ham xu ly JSON manh me hon.
JSON_TABLE -- bien JSON thanh bang quan he
-- JSON_TABLE: tuong tu MySQL, chuyen JSON array thanh cac row
SELECT j.*
FROM orders
CROSS APPLY OPENJSON(order_data, '$.items')
WITH (
product_id INT '$.product_id',
qty INT '$.qty',
price DECIMAL(10,2) '$.price'
) AS j;
JSON_CONTAINS -- kiem tra gia tri trong JSON
-- Kiem tra JSON co chua gia tri 'error' trong field $.level khong
SELECT *
FROM logs
WHERE JSON_CONTAINS(payload, 'error', '$.level');
-- Tim san pham co tag 'sale'
SELECT *
FROM products
WHERE JSON_CONTAINS(tags, '"sale"');
JSON_PATH_EXISTS -- kiem tra path ton tai
SELECT *
FROM documents
WHERE JSON_PATH_EXISTS(metadata, '$.author.email');
| Function | Cong dung |
|---|---|
OPENJSON + WITH | Parse JSON array → bang (da co tu 2016) |
JSON_VALUE | Lay scalar value tu path |
JSON_QUERY | Lay object/array tu path |
JSON_MODIFY | Cap nhat gia tri trong JSON |
JSON_CONTAINS | Kiem tra gia tri co ton tai (2025) |
JSON_PATH_EXISTS | Kiem tra path co ton tai (2025) |
16. RegEx trong Truy van
SQL Server 2025 ho tro Regular Expressions native.
REGEXP_LIKE -- tim kiem pattern
-- Tim tai lieu chua tu khoa nhay cam (case-insensitive)
SELECT *
FROM documents
WHERE REGEXP_LIKE(content, '\b(confidential|secret|internal)\b', 'i');
-- Validate email format
SELECT *
FROM users
WHERE NOT REGEXP_LIKE(email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
REGEXP_SUBSTR -- trich xuat du lieu tu text
-- Trich xuat dia chi IP tu log
SELECT
id,
REGEXP_SUBSTR(description, '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') AS ip_address
FROM logs;
-- Trich xuat so dien thoai
SELECT REGEXP_SUBSTR(notes, '\d{2,4}[-\s]?\d{3,4}[-\s]?\d{4}') AS phone
FROM contacts;
REGEXP_REPLACE -- thay the pattern
-- Mask so dien thoai trong log
SELECT REGEXP_REPLACE(
log_message,
'\d{2,4}[-\s]?\d{3,4}[-\s]?\d{4}',
'***MASKED***'
) AS sanitized_message
FROM audit_logs;
REGEXP_COUNT -- dem so lan xuat hien
-- Dem so URL trong bai viet
SELECT
id,
REGEXP_COUNT(content, 'https?://[^\s]+') AS url_count
FROM articles;
LIKE voi wildcard (%, _, [abc]) don gian, hoac dung CLR integration / external script de goi .NET Regex. 2025 co native RegEx -- nhanh hon nhieu, khong can CLR.REGEXP_LIKE tren bang lon khong co WHERE loc truoc. Pattern nen cang cu the cang tot, tranh backtracking qua sau.17. Intelligent Query Processing (IQP) -- Tong quan & Cap nhat 2025
IQP la bo tinh nang tu dong cai thien query performance, khong can thay doi code.
Bang tong hop IQP qua cac phien ban
| Tinh nang IQP | 2017 | 2019 | 2022 | 2025 |
|---|---|---|---|---|
| Adaptive Joins | ✅ | ✅ | ✅ | ✅ |
| Interleaved Execution | ✅ | ✅ | ✅ | ✅ |
| Memory Grant Feedback | ✅ | ✅ | ✅ (cai thien) | ✅ (cai thien) |
| Table Variable Deferred Compilation | -- | ✅ | ✅ | ✅ |
| Scalar UDF Inlining | -- | ✅ | ✅ | ✅ |
| Degree of Parallelism Feedback (DOP Feedback) | -- | -- | ✅ | ✅ (cai thien) |
| CE Feedback | -- | -- | -- | ✅ NEW |
| Optimized Locking | -- | -- | -- | ✅ NEW |
| Parameter Sensitive Plan (PSPO) | -- | -- | -- | ✅ NEW |
| Optional Parameter Plan (OPPO) | -- | -- | -- | ✅ NEW |
- 2017: Adaptive Joins + Interleaved Execution + Memory Grant Feedback (3 tinh nang goc).
- 2019: Scalar UDF Inlining + Table Variable Deferred Compilation.
- 2022: DOP Feedback + Memory Grant Feedback cai thien (persisted).
- 2025: AI-driven -- CE Feedback hoc tu workload, Optimized Locking loai bo lock escalation, PSPO/OPPO tu dong chon plan theo tham so.
- Khac biet cot loi: 2017-2022 la "heuristic cai thien", 2025 la "ML tu hoc lien tuc".
Bat/tat IQP features
-- Kiem tra IQP features dang bat
SELECT name, value_in_use
FROM sys.configurations
WHERE name LIKE '%intelligent%'
OR name LIKE '%feedback%'
OR name LIKE '%adaptive%';
-- Bat tat ca IQP features (2025, mac dinh ON)
ALTER DATABASE SCOPED CONFIGURATION
SET CE_FEEDBACK = ON,
DOP_FEEDBACK = ON,
MEMORY_GRANT_FEEDBACK = ON,
OPTIMIZED_LOCKING = ON,
PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = ON;
18. Azure SQL Hyperscale — khác biệt về isolation, failover, scale-out
Azure SQL Database Hyperscale là kiến trúc storage-compute tách rời, khác biệt đáng kể so với SQL Server boxed product về cách hoạt động transaction, failover, và read scale.Isolation & transaction
| SQL Server on-prem | Azure SQL Hyperscale | |
|---|---|---|
| Default isolation | Read Committed (lock-based) | Read Committed Snapshot (RCSI) ON mặc định |
| Snapshot / MVCC | Phải bật READ_COMMITTED_SNAPSHOT thủ công | Bật sẵn — version store dùng page server (storage layer riêng) |
| TempDB | Local SSD, contention bottleneck | Không dùng TempDB cho version store — tránh PAGELATCH bottleneck |
| Long transaction | Bloat version store trong TempDB | Version store nằm trên page server (hầu như không giới hạn) |
| Lock memory | Shared global lock manager | Per-node lock manager (scale-out tự nhiên hơn) |
"Hyperscale bật RCSI mặc định và không dùng TempDB cho version store. Page server lưu tất cả version → loại bỏ hoàn toàn TempDB contention, PAGELATCH bottleneck. Long transaction không gây bloat TempDB. Đây là lý do Hyperscale phù hợp cho workload mixed OLTP + reporting."
Failover & High Availability
┌──────────────┐ ┌──────────────┐
│ Compute │◄────►│ Compute │
│ (Primary) │ │ (Secondary) │
└──────┬───────┘ └──────┬───────┘
│ │
└──────────┬──────────┘
│
┌────────▼────────┐
│ Page Server │ ← Storage layer shared giữa các replica
│ (Data + Log) │
└─────────────────┘
| SQL Server on-prem | Azure SQL Hyperscale | |
|---|---|---|
| Failover time | 30s-2 phút (AG failover) | < 10 giây (compute node restart + reattach page server) |
| Data sync | Sync/async commit qua AG | Không cần sync data — page server dùng chung |
| RPO | 0 với sync commit, >0 với async | 0 RPO (log ghi vào page server trước khi ACK) |
| Read replicas | Tối đa 8 secondary (AG), cần license | 0-30 named replicas (không giới hạn bởi AG), provision nhanh |
| Replica lag | Vài ms đến vài giây (tuỳ sync mode) | Sub-second (page server push log trực tiếp) |
Scale-out reads — tính năng đặc thù Hyperscale
-- Connect string cho read-only replica trong Hyperscale
-- Server=tcp:myserver.database.windows.net;Database=mydb;ApplicationIntent=ReadOnly;
-- Không cần cấu hình AG listener thủ công — Azure tự route
-- Mỗi named replica có connection string riêng
- Named replicas: tạo replica với tên riêng, có thể có compute size khác primary (VD: primary 8 vCore, replica 40 vCore cho reporting nặng).
- High-availability replicas: free, tự động tạo cho HA (không dùng cho read workload).
- Mỗi replica dùng chung page server → không cần sync data → tạo replica trong < 1 phút, không cần seed database hàng giờ như AG on-prem.
- Licensing: named replicas tính riêng vCore cost; HA replicas miễn phí (đã bao gồm trong tier).
Khi nào dùng Hyperscale vs SQL Server on-prem vs Azure SQL thường?
| Use case | Khuyến nghị |
|---|---|
| OLTP < 100GB, RTO thấp | Azure SQL (DTU/vCore) |
| OLTP + real-time reporting, > 1TB | Hyperscale |
| Cần 10+ read replicas, sub-second lag | Hyperscale |
| Regulatory: data phải on-prem | SQL Server + AG |
| Full Enterprise feature (SSIS, SSAS) | SQL Server on-prem / Azure VM |
| Dev/test local | Docker container |
SQL Database on Microsoft Fabric
SQL Database trong Fabric là 1 database engine SaaS-native, dùng chung codebase với SQL Server 2025:-- Tạo database trong Fabric (không cần provision server!)
CREATE DATABASE MyFabricDB;
-- Auto-provisioned, auto-scale, auto-backup
-- Dùng T-SQL y hệt SQL Server
CREATE TABLE products (id INT, name NVARCHAR(200), embedding VECTOR(1536));
INSERT INTO products VALUES (1, 'Widget', @embedding);
- Zero server management — không cần setup instance, không patch, không backup config.
- Tích hợp Fabric ecosystem: OneLake, Power BI, notebook, data pipeline.
- Copilot tích hợp sẵn — natural language → T-SQL trong Fabric portal.
- Phù hợp cho analytics project, data warehouse nhỏ, team muốn SQL mà không muốn quản trị server.
2. Cú pháp cơ bản
DDL, DML, kiểu dữ liệu, NULL handling, ràng buộc — nền tảng T-SQL cho SQL Server 2025.
4. Đặc thù và Performance
Đặc thù SQL Server 2025 — JSON, Vector Index (DiskANN), Optimized Locking, RegEx, temporal table. Index, execution plan, tuning, query optimization, AI integration, benchmarks.