Kỹ thuật thao tác dữ liệu hiệu quả
Tập hợp các kỹ thuật ghi/cập nhật dữ liệu ở tầng database thay vì tầng ứng dụng.
1. Tranh chấp khóa (Lock Contention) → Bộ đếm phân tán
Post viral: hàng nghìn like mỗi giây. Mỗi UPDATE likes_count = likes_count + 1 phải lock row → các update xếp hàng chờ nhau (nghẽn cổ chai).
-- Giải pháp: thay vì 1 row, tạo 100 row cho mỗi counter (fanout)
INSERT INTO post_statistics (post_id, fanout, likes_count)
VALUES (1475870220422107137, FLOOR(RAND() * 100), 1)
ON DUPLICATE KEY UPDATE likes_count = likes_count + VALUES(likes_count);
-- Khi đọc: SUM tất cả fanout rows
SELECT SUM(likes_count) FROM post_statistics WHERE post_id = 1475870220422107137;
-- → Throughput tăng gấp 100 lần vì 100 row khác nhau update song song được2. UPDATE JOIN - cập nhật dữ liệu từ bảng khác
-- MySQL:
UPDATE products
JOIN categories USING(category_id)
SET price = price_base - price_base * categories.discount;
-- PostgreSQL:
UPDATE products
SET price = price_base - price_base * categories.discount
FROM categories
WHERE products.category_id = categories.category_id;Thay vì loop trong application code, một query duy nhất xử lý tất cả.
3. RETURNING - lấy dữ liệu ngay sau khi thay đổi (PostgreSQL)
DELETE FROM sessions WHERE ip = '127.0.0.1'
RETURNING id, user_agent, last_access;
-- Xóa VÀ trả về data trong cùng 1 query. Hoạt động với DELETE, INSERT, UPDATE.4. Xóa dòng trùng lặp bằng CTE
Xem CTE - ROW_NUMBER() OVER(PARTITION BY ...) + DELETE, thay vì logic chunking ở tầng ứng dụng.
5. FOR UPDATE - khóa dòng ở tầng database
START TRANSACTION;
SELECT balance FROM account WHERE account_id = 7 FOR UPDATE;
-- Row bị lock, không ai khác modify được cho đến khi COMMIT
-- Application xử lý logic...
UPDATE account SET balance = 540 WHERE account_id = 7;
COMMIT;
-- Lock tự động release khi transaction kết thúc hoặc client disconnectƯu điểm so với application-level locking: không lo quên unlock, không lo crash để lại lock “treo”.
Liên quan
- UPDATE và DELETE cũng cần Index - phần WHERE vẫn cần index
- Query Tips hữu ích - các mẹo SELECT
- Pre-sort và Pre-aggregation - bộ đếm phân tán là dạng pre-aggregation có fanout