NULL và Index - Giá trị đặc biệt cần đặc biệt chú ý

NULL trong SQL nghĩa là “không biết” (unknown), KHÔNG phải “rỗng” hay “zero”.

Behavior quan trọng

NULL = NULLNULL  (không phải TRUE!)
NULL != NULLNULL  (không phải TRUE!)
NULL > 5NULL
NULL + 10NULL
-- Bất kỳ phép tính nào với NULL đều trả về NULL
-- Trong context WHERE, NULL được coi như FALSE

NULL trong sort order

SQL standard không quy định - mỗi database tự quyết:

  • MySQL: NULL đứng trước (nhỏ nhất)
  • PostgreSQL: NULL đứng sau (lớn nhất)

Kiểm soát vị trí NULL trong ORDER BY: MySQL dùng ORDER BY country IS NULL, country ASC; PostgreSQL dùng NULLS FIRST / NULLS LAST.

NULL và Index

  • IS NULL hoạt động giống equality check - database nhảy thẳng đến block NULL entries → mọi nguyên tắc index áp dụng bình thường:
    WHERE supervisor_id IS NULL AND name = 'Huy'
    -- Index (supervisor_id, name) → Fast lookup NULL → tìm 'Huy' → hiệu quả!
  • IS NOT NULL hoạt động giống inequality - phải scan tất cả entries khác NULL. Nếu 95% nhân viên có supervisor → match 95% rows → database bỏ qua index.

Cái bẫy ngầm: NULL trong so sánh != (bug LOGIC, không chỉ performance)

-- Bảng users 1000 rows, 50 rows có country = NULL
SELECT * FROM users WHERE country != 'VN';
-- Bạn nghĩ: trả về tất cả trừ VN → 900 rows?
-- Thực tế: 850 rows! 50 rows NULL bị BỎ SÓT
-- Vì: NULL != 'VN' → NULL → coi như FALSE → không có trong kết quả

Cách fix:

-- Cách dài:
WHERE country != 'VN' OR country IS NULL
-- MySQL (NULL-safe equality operator):
WHERE NOT(country <=> 'VN')
-- PostgreSQL:
WHERE country IS DISTINCT FROM 'VN'

Liên quan