Vị trí bạn đang đứng
Người biết cú pháp
Thuộc CREATE INDEX, thuộc câu "giống mục lục sách", copy sẵn bảng "dùng loại nào khi nào" từ blog. Chạy được. Hỏi thêm một câu là bí.
// Database Từ Bản Chất™ · Phần 0–7
8 phần, đi từ storage internals tới MVCC tới cách planner ra quyết định.
Seq Scan on orders rows=12 Filter: user_id=42 AND status='paid' Rows Removed: 3,841,209Execution: 4823 ms
Nested Loop rows=12 Index Scan on users rows=1 Index Cond: id = 42 Index Scan on orders rows=12 Index Cond: user_id = 42 Filter: status = 'paid'Execution: 0.089 ms
// Nếu bạn thấy mình ở đây
Lần đầu nói ra, người phỏng vấn gật đầu. Lần sau họ hỏi thêm một câu, và câu đó lộ ra bạn chỉ thuộc ví dụ, chưa hiểu cái gì thật sự xảy ra bên dưới.
Query chậm, thêm index vào là hết chậm. Hỏi "tại sao" thì chỉ nói được "vì có index rồi".
Mở EXPLAIN ANALYZE, thấy Seq Scan dù bảng có index sẵn. Không biết đọc từ đâu, đóng lại, thử thêm index khác.
Phỏng vấn hỏi index hoạt động thế nào. Trả lời trôi tới "giống mục lục sách" rồi im.
Một bảng update nhiều, càng ngày càng chậm. VACUUM cho yên tâm, không hiểu vì sao nó chậm ngay từ đầu.
Vấn đề không phải bạn học chưa đủ. Là hầu hết chỗ dạy chỉ dừng ở đúng một ví dụ và một dòng lệnh, rồi coi như xong.
// Tại sao cần hỏi “tại sao”
Không phải người nhớ nhiều nhất. Là người hỏi “tại sao” nhiều nhất.
Kiến thức thì ngày mai đã thêm cái mới, cái cũ lạc hậu. Câu hỏi đúng thì khác: bạn giữ cả đời, và tự tìm câu trả lời mới mỗi khi hoàn cảnh thay đổi.
Người A
Hôm nay
Làm xong việc. Đóng laptop. Đi về.
1 năm sau
Vẫn y như vậy. Gặp lại bài cũ, vẫn phải tra cứu lại từ đầu.
5 năm sau
Vẫn y như vậy. Trong khi thế giới xung quanh đã đi tiếp từ lâu.
Người B
Hôm nay
Làm xong việc. Rồi dừng lại, hỏi thêm một câu “tại sao”.
1 năm sau
Hiểu sâu thêm một tầng. Thấy thứ người bên cạnh không thấy.
5 năm sau
Đã đứng ở chỗ rất khác, vì mỗi ngày gửi thêm một câu hỏi vào chính mình.
Mỗi câu “tại sao” bạn hỏi thêm giống như gửi tiết kiệm vào chính mình. Một mình thì chẳng thấy gì. Gửi đều đặn, một năm nhìn lại đã khác. Năm năm: bạn đứng ở chỗ rất ít người đứng được.
// Cái giá của việc bỏ qua
Mỗi lần bỏ qua câu hỏi “tại sao” là bạn cho phép mình trôi về phía trung bình: chỗ an toàn nhất, chỗ không sai nhưng cũng chỗ không ai nhớ đến nhất.
// Điều cuối cùng muốn nói
Câu trả lời thì ngày mai đã cũ.
Câu hỏi đúng thì không bao giờ cũ, vì nó tự sinh ra câu trả lời mới mỗi khi bạn cần.
// Cách nhìn thay đổi tất cả
Kiến thức về database nằm trên một trục: một đầu là thuộc cú pháp, đầu kia là hiểu vì sao Postgres quyết định vậy. Gần hết tài liệu chỉ đưa bạn tới nửa đường.
Vị trí bạn đang đứng
Thuộc CREATE INDEX, thuộc câu "giống mục lục sách", copy sẵn bảng "dùng loại nào khi nào" từ blog. Chạy được. Hỏi thêm một câu là bí.
Sau khi học xong
Biết dữ liệu nằm ở đâu, cây tìm kiểu gì, ghi tốn gì, version nào "dính" theo index, và vì sao planner chọn scan này chứ không phải scan kia.
Bạn biết cách dùng. Chỉ là chưa ai chỉ bạn Postgres đang nghĩ gì trước khi ra quyết định đó.
// Outline 8 phần
Mỗi phần dựa vào aha moment của phần trước, không phải danh sách mẹo rời rạc.
Vì sao có bảng đã tạo index mà Postgres vẫn chọn Seq Scan? Câu hỏi dẫn dắt cả khóa, trả lời đầy đủ nằm ở Phần 6.
Dữ liệu thật sự nằm ở đâu: page, tuple, heap. Nền cho mọi phần sau.
Không phải "giống mục lục sách". Cấu trúc thật của B-tree và cách nó tìm dữ liệu.
Một INSERT/UPDATE thật sự tốn gì khi bảng có index. Chi phí ẩn không nằm trong tutorial nào.
Vì sao index scan vẫn đụng dead tuple, và HOT Update giải quyết chuyện đó ra sao. Aha moment mạnh nhất khóa học.
Hành vi thật của B-tree khi bảng lớn dần: không còn ví dụ đồ chơi 50 dòng.
Selectivity, cost, lý do thật đằng sau Seq Scan hay Index Scan. Trả lời trọn vẹn cho Phần 0.
Đọc được Postgres đang tính gì trong một query thật, thôi đoán mò.
// Niềm tin đang giữ bạn lại
Nghe hợp lý, ai cũng tin, nên chẳng ai buồn nghi ngờ. Gỡ được thì đi được nửa đường rồi.
"Prisma/TypeORM lo hết, cần gì biết index."
ORM sinh SQL, không sinh hiểu biết. Query chậm ở production, ORM không giải thích hộ bạn đâu. Người gỡ được là người hiểu bên dưới, không phải người thuộc API ORM.
"Học course index rồi, khóa nào cũng như nhau."
Phần lớn khóa dừng ở ví dụ mục lục sách và cú pháp CREATE INDEX, đúng 10% câu chuyện. MVCC ảnh hưởng index thế nào, vì sao update chậm dần: gần như không ai đụng tới, vì khó dạy hơn cú pháp nhiều.
"AI viết query hộ rồi, học sâu DB làm gì."
AI viết đúng cú pháp. Nó không biết vì sao query đó chậm trên data thật của bạn, không đọc EXPLAIN ANALYZE hộ bạn lúc production sập. Phần AI làm tốt là gõ code. Phần hiểu để ra quyết định vẫn là việc của bạn.
"Làm lâu tự khắc hiểu sâu."
Việc hàng ngày không ép bạn hiểu bản chất: query chạy được là xong task, chẳng ai bắt giải thích tại sao. Nhiều người làm cả chục năm vẫn dừng ở lớp "dùng được". Hiểu sâu là một quyết định chủ động, không tự tới theo số năm.
"Tài liệu tiếng Anh đầy, học tiếng Việt làm gì."
Tài liệu có thật, nhưng phần lớn là docs khô hoặc sách vài trăm trang viết cho người đã có nền sẵn. Không phải không có, mà tự học một mình theo đúng thứ tự không dễ.
"Cái này để lên senior học cũng chưa muộn."
Người có mác senior ở công ty này có khi chỉ là junior ở chỗ khác: cái mác là do người khác gán, không phải thước đo giá trị thật. Đừng thần thánh hóa role; quan trọng là skill thực của bạn, và skill thì không tự tới khi bạn đợi có mác rồi mới bắt đầu học.
// Học kiểu cũ, học kiểu này
Thuộc "B-tree cho equality, GIN cho full-text" như học bảng cửu chương.
Hiểu cấu trúc B-tree và heap thật, tự suy ra được loại index nào hợp lý.
Query chậm, thêm index, xóa index, thử lại, tới khi nào work thì thôi.
Đọc EXPLAIN ANALYZE, biết chính xác Postgres đang cân nhắc gì trước khi chọn scan.
Đọc EXPLAIN ANALYZE như đọc chữ Hán, không hiểu Postgres đang tính gì.
Hiểu MVCC tạo dead tuple ra sao, tự giải thích được vì sao update chậm dần.
Phỏng vấn hỏi sâu về DB là lái sang nói chuyện framework.
Trả lời câu hỏi DB trong phỏng vấn bằng lý do, không phải định nghĩa học thuộc.
Học xong quên nhanh, không có gốc, chỉ là mảnh vá rời rạc.
Kiến thức có gốc, dùng lại được cho mọi hệ thống chạy Postgres sau này.
Không phải đường tắt bỏ qua kỹ thuật. Là học đúng lớp, thứ ít tài liệu tiếng Việt chịu dạy.
// Khóa này không dành cho tất cả mọi người
// Tại sao mình làm khóa này
Có một buổi phỏng vấn mình nhớ khá rõ. Bên kia hỏi: "Bảng payment của em càng ngày càng nhiều update, query check trạng thái giao dịch chậm dần. Em xử lý sao?" Mình trả lời VACUUM, reindex, rồi im. Vì thật ra mình chỉ biết làm, chưa hiểu tại sao nó xảy ra.
Tối hôm đó mình lục lại hết chỗ mình từng học về index: course, blog, video. Rồi phát hiện một điều khá buồn cười: gần hết chỗ chỉ dạy đúng một ví dụ (index giống mục lục sách) và một dòng lệnh (CREATE INDEX). Không ai kể MVCC tạo tuple version mới mỗi lần update, và index B-tree phải đi qua cả những version đã chết trước khi tìm ra version còn sống. Bảng update nhiều thì dead tuple tích lại, index scan phải bơi qua nhiều rác hơn, đó mới là lý do thật, không phải "bảng lớn thì chậm" chung chung.
Lúc hiểu ra HOT Update: Postgres update tại chỗ, không đụng index, nếu cột update không nằm trong index. Mình mới thấy rõ cái mình thiếu suốt bao lâu nay không phải thêm kỹ thuật. Là hiểu đúng thứ tự một database engine thật sự vận hành.
Khóa này là chỗ mình lấp cái khoảng đó. Không phải thêm một bảng "loại index nào dùng khi nào", mà đi từ storage, tới cách ghi dữ liệu, tới MVCC, tới cách planner ra quyết định. Từ bản chất, đúng nghĩa đen, không phải tagline.
// Câu hỏi thường gặp
// Bước tiếp theo
Không xin email, không đẩy bạn qua chuỗi bán hàng. Outline và trạng thái sản xuất đã ở ngay phía trên. Thấy đúng thứ đang thiếu thì mua trọn bộ ngay.
P.S. Nếu mỗi lần bị hỏi "tại sao" về index, MVCC, hay planner, câu trả lời duy nhất của bạn là "giống mục lục sách", thì vấn đề không nằm ở việc bạn chưa đủ chăm. Bạn đang dừng ở đúng lớp mà 90% tài liệu để bạn dừng lại. Đây là phần còn lại của câu chuyện.