Các bạn đã thực sự hiểu và biết cách dùng Index chưa?

Apr 17, 2022

Hế lôôôôô tất cả anh chị em 😋😜, hehe lại là mình đây và hôm nay mình xin tổng hợp lại một số kiến thức buổi sharing trước đó về chủ đề Index trong tối ưu hóa DB. Mọi người cùng tham khảo và cho mình xin ý kiến nhé 😘😘😘😘😘😘😘

Ố kê ố kê, vào nội dung chính nào 😎

Đầu tiên chúng ta cùng đi tìm hiểu xem Index trong DB nó là cái gì đã nhé.

Ở trang chủ không có định nghĩa hay khái niệm Index là gì nên mình xin đưa ra khái niệm về Index theo quan điểm cá nhân của mình như sau.

"Index là một loại cấu trúc dữ liệu giúp cải thiện tốc độ tìm kiếm trên một bảng, làm giảm chi phí thực hiện truy vấn"

Ok, tạm coi như khái niệm của Index là vậy đi, thế thì Index nó hoạt động như thế nào??? như thế nào nàoooooooooo ? Mình xin nói về cách hoạt động của Index như sau:

Index hoạt động giống như con trỏ đến các hàng trong bảng, cho phép truy vấn nhanh chóng xác định hàng nào phù hợp với điều kiện trong mệnh đề WHERE và truy xuất các giá trị cột khác cho các hàng đó.

Để cụ thể và dễ hiểu hơn thì mình xin đưa ra ví dụ sau:

Trên đường Hoàng Quốc Việt có 10 nghìn ngôi nhà chưa được đánh số, và mỗi lần anh shipper đi giao đồ thì anh ta phải đi lần lượt từ số nhà 1 đến số nhà 10.000 để hỏi xem có nhà nào order đơn hàng này ko, nếu đúng thì giao hàng rồi lấy tiền, không thì lại tiếp tục đi và hỏi, đi tiếp, hỏi tiếp. Ôi má ơi tôi chết đây 🙃

Nhưng nếu 10.000 ngôi nhà trên đường Hoàng Quốc Việt được đánh số nhà thì sao nhỉ? 🤔. Thì rất đơn dản thôi, anh shipper chỉ việc đến đúng số nhà đấy giao hàng xong lấy tiền, không cần phải hỏi lần lượt từng nhà một, dễ hơn bóc bánh đúng không nào :))

Và Index trong DB cũng vậy, nếu có Index thì lúc truy vấn nó sẽ lập tức đến hàng có bản ghi phù hợp để truy xuất dữ liệu mà không cần phải lặp qua từng dòng.

Index hấp dẫn như vậy thì liệu lúc nào ta cũng nên xử dụng Index không và chỉ nên dùng Index trong trường hợp nào? thì dưới đây mình có liệt kê ra những trường hợp không nên  và nên dùng Index.

  • Không nên dùng Index cho các ứng dụng thường xuyên create, update data vì mỗi lần create hay update thì Index lại phải đánh lại Index cho tất cả các records trong bảng đó
  • Chỉ nên dùng Index cho các bảng có dung lượng đủ lớn ( > 10.0000 records ) vì nếu dữ liệu không đủ lớn thì sẽ không ảnh hưởng qúa nhiều đến việc mình có dùng hay không dùng Index
  • Chỉ nên dùng Index cho các trường thường xuyên sử dụng mệnh đề where
  • Tránh dùng Index với các trường như text, description, nếu có sử dụng nên sử dụng 5-10 ký tự đầu - nếu đánh Index cho toàn bộ ký tự sẽ gây lãng phí rất nhiều tài nguyên
  • Không nên dùng Index cho các trường trùng lặp giá trị quá nhiều như flag, status, true hay false gì đó
  • Không dùng Index với các toán tử phủ nhận như != , NOT IN … (liên quan đến cấu trúc dữ liệu B-tree) các bạn có thể tìm hiểu thêm
  • Không nên dùng Index cho các trường là NULL

Đó là những trường hợp mình đã liệt kê, còn thiếu trường hợp nào thì các bạn bổ xung giúp mình nhé 😊

Oke! Khái niệm mình đã biết rồi, cách hoạt động, nên hay không nên dùng cũng đã biết rồi, vậy thì dùng nó như thế nào?

Giả sử rằng một bảng có Index một cột như sau:

CREATE TABLE test (
    id         INT NOT NULL,
    col1 CHAR(30) NOT NULL,
    col2 CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX col1_key (col1)
);

Index col1_key sẽ hoạt động với các câu lệnh như sau:

SELECT * FROM test WHERE col1 = 'Jones';

SELECT * FROM test WHERE col1 = 'Jones' AND (col1 = 'John' OR col2 = 'Jon');

Tuy nhiên Index sẽ không hoạt động với các câu lệnh sau:

SELECT * FROM test WHERE col1 != 'Jones';

SELECT * FROM test WHERE col1 = 'Jones' OR col2 = 'Jon';

Như chúng ta đã nói ở trên, mặc định khi tạo Index sẽ có cấu trúc dạng B-Tree và nó không hoạt động với những tóan tử phủ định và nếu dùng điều kiện OR thì nên để OR trong ngoặc đơn như thế này

SELECT * FROM test WHERE col1 = 'Jones' AND (col1 = 'John' OR col2 = 'Jon');

Giả sử rằng một bảng có Index nhiều cột như sau:

CREATE TABLE test (
    id         INT NOT NULL,
    col1  CHAR(30) NOT NULL,
    col2  CHAR(30) NOT NULL,
    col3  CHAR(30) NOT NULL,
    col4  CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX name (col1,col2)
);

Index name là một chỉ mục trên cột col1col2 . Index có thể được sử dụng để tra cứu trong các truy vấn chỉ định các giá trị trong một phạm vi đã biết cho các kết hợp của gía trị col1col2 . Nó cũng có thể được sử dụng cho các truy vấn chỉ định một giá trị col1   vì cột đó là tiền tố ngoài cùng bên trái của chỉ mục. Do đó, Index name được sử dụng để tra cứu trong các truy vấn sau:

SELECT * FROM test WHERE col1 = 'Jones';

SELECT * FROM test
  WHERE col1='Jones' AND col2='John';

SELECT * FROM test
  WHERE col1='Jones'
  AND (col2='John' OR col1='Jon');

SELECT * FROM test
  WHERE col1='Jones'
  AND col2 >='M' AND col2 < 'N';

Tuy nhiên, Index name không được sử dụng để tra cứu trong các truy vấn sau:

SELECT * FROM test WHERE col1='John';

SELECT * FROM test
  WHERE col1='Jones' OR col2='John';

Nếu bảng có Index nhiều cột, bất kỳ tiền tố ngoài cùng bên trái nào của Index cũng có thể được trình tối ưu hóa sử dụng để tra cứu các hàng. Ví dụ: nếu bạn có Index ba cột (col1, col2, col3), bạn đã bật khả năng tìm kiếm được lập chỉ mục (col1), (col1, col2)(col1, col2, col3).

MySQL không thể sử dụng Index để thực hiện tra cứu nếu các cột không tạo thành tiền tố ngoài cùng bên trái của Index như (col2)(col2, col3)

:)) Oke Oke  đến đây chắc là các bạn bắt đầu thấy dài rồi đúng không, nên mình xin dừng bài viết ở đây

Mình rất hy vọng bài viết có thể giúp ích hay đọng lại trong các bạn 1 điều gì đó 😊

Cuối cùng chúc các bạn thật nhiều sức khỏe (có sức khỏe là có tất cả)

Nếu có bất kỳ thắc mắc hoặc thảo luận nào các bạn vui lòng cho mình xin ý kiến nhé :))

Cảm ơn tất cả mọi người 😊💙💚💕❤️♥

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.