MariaDB
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> MariaDB

Hướng dẫn về Chỉ mục MySQL

Khi đề cập đến việc tối ưu hóa truy vấn MySQL, chỉ mục là một trong những điều đầu tiên được đề cập. Hôm nay, chúng ta sẽ thử xem tại sao chúng lại quan trọng như vậy.

Chỉ mục là gì?

Nói chung, chỉ mục là danh sách các bản ghi theo thứ tự bảng chữ cái với các tham chiếu đến các trang mà chúng được đề cập. Trong MySQL, chỉ mục là một cấu trúc dữ liệu được sử dụng để nhanh chóng tìm thấy các hàng. Chỉ mục còn được gọi là khóa và những khóa đó rất quan trọng để có hiệu suất tốt - khi dữ liệu ngày càng lớn, nhu cầu sử dụng chỉ mục đúng cách có thể ngày càng trở nên quan trọng hơn. Sử dụng chỉ mục là một trong những cách mạnh mẽ nhất để cải thiện hiệu suất truy vấn - nếu chỉ mục được sử dụng đúng cách, hiệu suất truy vấn có thể tăng lên hàng chục hoặc thậm chí hàng trăm lần.

Hôm nay, chúng tôi sẽ cố gắng giải thích những lợi ích và hạn chế cơ bản của việc sử dụng chỉ mục trong MySQL. Hãy nhớ rằng chỉ mục MySQL thôi đã xứng đáng với cả một cuốn sách nên bài đăng này sẽ không bao gồm tất cả mọi thứ, nhưng nó sẽ là một điểm khởi đầu tốt. Đối với những người quan tâm đến cách các chỉ mục hoạt động ở cấp độ sâu hơn, hãy đọc cuốn sách Thiết kế chỉ mục cơ sở dữ liệu quan hệ và các trình tối ưu hóa của Tapio Lahdenmäki và Michael Leach sẽ cung cấp thêm thông tin chi tiết.

Lợi ích của việc sử dụng chỉ mục

Có một số lợi ích chính của việc sử dụng các chỉ mục trong MySQL và những lợi ích này như sau:

  • Các chỉ mục cho phép nhanh chóng tìm thấy các hàng phù hợp với mệnh đề WHERE;
  • Các chỉ mục có thể giúp các truy vấn tránh tìm kiếm qua các hàng nhất định, do đó giảm lượng dữ liệu mà máy chủ cần kiểm tra - nếu có sự lựa chọn giữa nhiều chỉ mục, MySQL thường sử dụng chỉ mục chọn lọc nhất, đó là chỉ số tìm số lượng hàng nhỏ nhất;
  • Các chỉ mục có thể được sử dụng để lấy các hàng từ các bảng khác trong các hoạt động JOIN;
  • Chỉ mục có thể được sử dụng để tìm giá trị nhỏ nhất hoặc lớn nhất của một cột cụ thể có sử dụng chỉ mục;
  • Chỉ mục có thể được sử dụng để sắp xếp hoặc nhóm bảng nếu các thao tác được thực hiện trên tiền tố ngoài cùng bên trái của chỉ mục - tương tự, tiền tố ngoài cùng bên trái của chỉ mục nhiều cột cũng có thể được trình tối ưu hóa truy vấn sử dụng để tra cứu các hàng;
  • Các chỉ mục cũng có thể được sử dụng để lưu I / O đĩa - khi một chỉ mục bao phủ được sử dụng, một truy vấn có thể trả về các giá trị ngay từ cấu trúc chỉ mục lưu I / O đĩa.

Tương tự, có nhiều loại chỉ mục:

  • INDEX là một loại chỉ mục trong đó các giá trị không cần phải là duy nhất. Loại chỉ mục này chấp nhận giá trị NULL;
  • UNIQUE INDEX thường được sử dụng để xóa các hàng trùng lặp khỏi bảng - loại chỉ mục này cho phép các nhà phát triển thực thi tính duy nhất của các giá trị hàng;
  • FULLTEXT INDEX là một chỉ mục được áp dụng trên các trường sử dụng khả năng tìm kiếm toàn văn. Loại chỉ mục này tìm các từ khóa trong văn bản thay vì so sánh trực tiếp các giá trị với các giá trị trong chỉ mục;
  • CHỈ SỐ MÔ TẢ là chỉ mục lưu trữ các hàng theo thứ tự giảm dần - trình tối ưu hóa truy vấn sẽ chọn loại chỉ mục này khi truy vấn yêu cầu thứ tự giảm dần. Loại chỉ mục này đã được giới thiệu trong MySQL 8.0;
  • PRIMARY KEY cũng là một chỉ mục. Tóm lại, KHÓA CHÍNH là một cột hoặc một tập hợp các cột xác định từng hàng trong bảng - thường được sử dụng cùng với các trường có thuộc tính AUTO_INCREMENT. Loại chỉ mục này không chấp nhận các giá trị NULL và sau khi được đặt, các giá trị trong KHÓA CHÍNH không thể thay đổi.

Bây giờ, chúng ta sẽ thử xem xét cả lợi ích và hạn chế của việc sử dụng chỉ mục trong MySQL. Chúng ta sẽ bắt đầu với phần mở rộng có lẽ được thảo luận thường xuyên nhất - tăng tốc các truy vấn phù hợp với mệnh đề WHERE.

Tăng tốc Truy vấn Khớp với Mệnh đề WHERE

Chỉ mục thường được sử dụng để tăng tốc các truy vấn tìm kiếm phù hợp với mệnh đề WHERE. Lý do tại sao một chỉ mục làm cho các hoạt động tìm kiếm như vậy nhanh hơn khá đơn giản - các truy vấn sử dụng một chỉ mục sẽ tránh được việc quét toàn bộ bảng.

Để tăng tốc các truy vấn phù hợp với mệnh đề WHERE, bạn có thể sử dụng câu lệnh EXPLAIN trong MySQL. Câu lệnh EXPLAIN SELECT sẽ cung cấp cho bạn một số thông tin chi tiết về cách trình tối ưu hóa truy vấn MySQL thực thi truy vấn - nó cũng có thể cho bạn biết liệu truy vấn được đề cập có sử dụng một chỉ mục hay không và nó sử dụng chỉ mục nào. Hãy xem giải thích truy vấn sau:

mysql> EXPLAIN SELECT * FROM demo_table WHERE field_1 = “Demo” \G;

*************************** 1. row ***************************

<...>

possible_keys: NULL

key: NULL

key_len: NULL

<...>

Truy vấn trên không sử dụng chỉ mục. Tuy nhiên, nếu chúng tôi thêm chỉ mục trên “field_1”, chỉ mục sẽ được sử dụng thành công:

mysql> EXPLAIN SELECT * FROM demo_table WHERE field_1 = “Demo” \G;

*************************** 1. row ***************************

<...>

possible_keys: field_1

key: field_1

key_len: 43

<...>

Cột could_keys mô tả các chỉ mục khả thi mà MySQL có thể chọn, cột khóa mô tả chỉ mục thực sự được chọn và cột key_len mô tả độ dài của khóa đã chọn.

Trong trường hợp này, MySQL sẽ thực hiện tra cứu các giá trị trong chỉ mục và trả về bất kỳ hàng nào chứa giá trị được chỉ định - kết quả là truy vấn sẽ nhanh hơn. Mặc dù các chỉ mục giúp các truy vấn nhất định nhanh hơn, nhưng có một số điều bạn cần lưu ý nếu bạn muốn các chỉ mục của mình giúp các truy vấn của bạn:

  • Cô lập các cột của bạn - MySQL không thể sử dụng chỉ mục nếu các cột mà chỉ mục được sử dụng không bị cô lập. Ví dụ:một truy vấn như thế này sẽ không sử dụng chỉ mục:
    SELECT field_1 FROM demo_table WHERE field_1 + 5 = 10;

Để giải quyết vấn đề này, hãy để riêng cột đứng sau mệnh đề WHERE - đơn giản hóa truy vấn của bạn càng nhiều càng tốt và cô lập các cột;

  • Tránh sử dụng các truy vấn LIKE có ký tự đại diện đứng trước - trong trường hợp này, MySQL sẽ không sử dụng chỉ mục vì ký tự đại diện đứng trước có nghĩa là có thể có bất kỳ thứ gì trước văn bản. Nếu bạn phải sử dụng các truy vấn LIKE với các ký tự đại diện và muốn các truy vấn sử dụng các chỉ mục, hãy đảm bảo rằng ký tự đại diện nằm ở cuối câu lệnh tìm kiếm.

Tất nhiên, việc tăng tốc các truy vấn phù hợp với mệnh đề WHERE cũng có thể được thực hiện theo những cách khác (ví dụ:phân vùng), nhưng vì đơn giản, chúng tôi sẽ không xem xét thêm điều đó trong bài đăng này.

Tuy nhiên, những gì chúng tôi có thể quan tâm là các loại chỉ mục khác nhau, vì vậy chúng tôi sẽ xem xét điều đó ngay bây giờ.

Loại bỏ Giá trị Trùng lặp trong Cột - Chỉ mục DUY NHẤT

Mục đích của chỉ mục DUY NHẤT trong MySQL là thực thi tính duy nhất của các giá trị trong một cột. Để sử dụng chỉ mục DUY NHẤT, hãy chạy truy vấn TẠO CHỈ SỐ DUY NHẤT:

CREATE UNIQUE INDEX demo_index ON demo_table(demo_column);

You can also create a unique index when you create a table:

CREATE TABLE demo_table (
`demo_column` VARCHAR(100) NOT NULL,
UNIQUE KEY(demo_column)
);

Đó là tất cả những gì cần thiết để thêm một chỉ mục duy nhất vào bảng. Bây giờ, khi bạn cố gắng thêm một giá trị trùng lặp vào bảng, MySQL sẽ quay lại với lỗi sau:

#1062 - Duplicate entry ‘Demo’ for key ‘demo_column’

Chỉ mục FULLTEXT

Chỉ mục FULLTEXT là chỉ mục được áp dụng cho các cột sử dụng khả năng tìm kiếm toàn văn bản. Loại chỉ mục này có nhiều khả năng độc đáo bao gồm các từ dừng và chế độ tìm kiếm.

Danh sách từ dừng InnoDB có 36 từ trong khi danh sách từ dừng của MyISAM có 143. Trong InnoDB, các từ dừng được bắt nguồn từ bảng được đặt trong biến innodb_ft_user_stopword_table, ngược lại, nếu biến này không được đặt thì chúng được dẫn xuất từ biến innodb_ft_server_stopword_table. Nếu cả hai biến đó đều không được đặt, thì InnoDB sẽ sử dụng danh sách tích hợp sẵn. Để xem danh sách từ dừng InnoDB mặc định, hãy truy vấn bảng INNODB_FT_DEFAULT_STOPWORD.

Trong MyISAM, các từ dừng bắt nguồn từ tệp lưu trữ / myisam / ft_static.c. Biến ft_stopword_file cho phép thay đổi danh sách từ dừng mặc định. Từ dừng sẽ bị vô hiệu hóa nếu biến này được đặt thành một chuỗi trống, nhưng hãy nhớ rằng nếu biến này xác định một tệp, thì tệp đã xác định sẽ không được phân tích cú pháp để nhận xét - MyISAM sẽ coi tất cả các từ được tìm thấy trong tệp là từ dừng.

Chỉ mục FULLTEXT cũng nổi tiếng với các chế độ tìm kiếm độc đáo của nó:

  • Nếu chạy truy vấn tìm kiếm FULLTEXT không có bổ trợ, chế độ ngôn ngữ tự nhiên sẽ được kích hoạt. Chế độ ngôn ngữ tự nhiên cũng có thể được kích hoạt bằng cách sử dụng công cụ sửa đổi CHẾ ĐỘ NGÔN NGỮ TỰ NHIÊN;
  • Công cụ sửa đổi VỚI MỞ RỘNG QUERY cho phép chế độ tìm kiếm có mở rộng truy vấn. Chế độ tìm kiếm như vậy hoạt động bằng cách thực hiện tìm kiếm hai lần và khi tìm kiếm được chạy lần thứ hai, tập hợp kết quả sẽ bao gồm một số tài liệu có liên quan nhất từ ​​lần tìm kiếm đầu tiên. Nói chung, công cụ sửa đổi này hữu ích khi người dùng có một số kiến ​​thức ngụ ý (ví dụ:người dùng có thể tìm kiếm “cơ sở dữ liệu” và hy vọng thấy “InnoDB” và “MyISAM” trong tập kết quả);
  • Công cụ sửa đổi IN BOOLEAN MODE cho phép tìm kiếm bằng các toán tử boolean. Ví dụ:các toán tử +, - hoặc * sẽ hoàn thành các nhiệm vụ khác nhau - toán tử + sẽ xác định rằng giá trị phải có trong một hàng, toán tử - sẽ xác định rằng giá trị không được tồn tại và toán tử * sẽ hoạt động như một ký tự đại diện.

Truy vấn sử dụng chỉ mục FULLTEXT trông giống như sau:

SELECT * FROM demo_table WHERE MATCH(demo_field) AGAINST(‘value’ IN NATURAL LANGUAGE MODE);

Hãy nhớ rằng chỉ mục FULLTEXT thường hữu ích cho các phép toán MATCH () AGAINST () - không phải cho các phép toán WHERE, nghĩa là nếu mệnh đề WHERE sẽ được sử dụng, tính hữu ích của việc sử dụng các loại chỉ mục khác nhau sẽ không bị loại bỏ.

Cũng cần nhắc lại rằng các chỉ mục FULLTEXT có độ dài ký tự tối thiểu. Trong InnoDB, tìm kiếm FULLTEXT chỉ có thể được thực hiện khi truy vấn tìm kiếm có tối thiểu ba ký tự - giới hạn này được tăng lên bốn ký tự trong công cụ lưu trữ MyISAM.

MÔ TẢ Chỉ mục

Chỉ mục MÔ TẢ là một chỉ mục trong đó InnoDB lưu trữ các mục nhập theo thứ tự giảm dần - trình tối ưu hóa truy vấn sẽ sử dụng chỉ mục như vậy khi truy vấn yêu cầu thứ tự giảm dần. Chỉ mục như vậy có thể được thêm vào một cột bằng cách chạy một truy vấn như sau:

CREATE INDEX descending_index ON demo_table(column_name DESC);

Một chỉ mục tăng dần cũng có thể được thêm vào một cột - chỉ cần thay thế DESC bằng ASC.

CÁC TỪ KHÓA CHÍNH

KHÓA CHÍNH dùng làm mã định danh duy nhất cho mỗi hàng trong bảng. Cột có KHÓA CHÍNH phải chứa các giá trị duy nhất - không có giá trị NULL nào được phép sử dụng. Nếu một giá trị trùng lặp được thêm vào cột có KHÓA CHÍNH, MySQL sẽ phản hồi với lỗi # 1062:

#1062 - Duplicate entry ‘Demo’ for key ‘PRIMARY’

Nếu giá trị NULL được thêm vào cột, MySQL sẽ phản hồi với lỗi # 1048:

#1048 - Column ‘id’ cannot be null

Các chỉ mục chính đôi khi còn được gọi là chỉ mục nhóm (chúng ta sẽ thảo luận sau).

Bạn cũng có thể tạo chỉ mục trên nhiều cột cùng một lúc - những chỉ mục như vậy được gọi là chỉ mục đa cột.

Chỉ mục nhiều cột

Chỉ mục trên nhiều cột thường bị hiểu nhầm - đôi khi các nhà phát triển và DBA lập chỉ mục tất cả các cột riêng biệt hoặc lập chỉ mục chúng theo thứ tự sai. Để thực hiện các truy vấn sử dụng chỉ mục nhiều cột hiệu quả nhất có thể, hãy nhớ rằng thứ tự của các cột trong chỉ mục sử dụng nhiều hơn một cột là một trong những nguyên nhân phổ biến nhất gây nhầm lẫn trong không gian này - vì không có "cách này hoặc đường cao tốc ”Giải pháp về thứ tự chỉ mục, bạn phải nhớ rằng thứ tự chính xác của các chỉ mục nhiều cột phụ thuộc vào các truy vấn đang sử dụng chỉ mục. Mặc dù điều này có vẻ khá rõ ràng, nhưng hãy nhớ rằng thứ tự cột rất quan trọng khi xử lý các chỉ mục nhiều cột - hãy chọn thứ tự cột sao cho có chọn lọc nhất có thể cho các truy vấn sẽ chạy thường xuyên nhất.

Để đo độ chọn lọc cho các cột cụ thể, hãy lấy tỷ lệ giữa số giá trị được lập chỉ mục riêng biệt với tổng số hàng trong bảng - cột có độ chọn lọc cao hơn phải là cột đầu tiên .

Đôi khi bạn cũng cần lập chỉ mục các cột ký tự rất dài và trong trường hợp đó, bạn thường có thể tiết kiệm thời gian và tài nguyên bằng cách lập chỉ mục một vài ký tự đầu tiên - tiền tố - thay vì toàn bộ giá trị.

Chỉ mục tiền tố

Chỉ mục tiền tố có thể hữu ích khi các cột chứa các giá trị chuỗi rất dài, có nghĩa là việc thêm một chỉ mục trên toàn bộ cột sẽ tiêu tốn rất nhiều dung lượng đĩa. MySQL giúp giải quyết vấn đề này bằng cách cho phép bạn chỉ lập chỉ mục một tiền tố của giá trị do đó làm cho kích thước chỉ mục nhỏ hơn. Hãy xem:

CREATE TABLE `demo_table` (
`demo_column` VARCHAR(100) NOT NULL,
INDEX(demo_column(10))
);

Truy vấn trên sẽ tạo chỉ mục tiền tố trên cột demo chỉ lập chỉ mục 10 ký tự đầu tiên của giá trị. Bạn cũng có thể thêm chỉ mục tiền tố vào bảng hiện có:

CREATE INDEX index_name ON table_name(column_name(length));

Ví dụ:nếu bạn muốn lập chỉ mục 5 ký tự đầu tiên của demo_column trên demo_table, bạn có thể chạy truy vấn sau:

CREATE INDEX demo_index ON demo_table(demo_column(5));

Bạn nên chọn tiền tố đủ dài để cung cấp tính chọn lọc, nhưng cũng đủ ngắn để tạo khoảng trống. Tuy nhiên, điều này có thể dễ hơn làm - bạn cần thử nghiệm và tìm ra giải pháp phù hợp với mình.

Bao gồm các Chỉ mục

Chỉ mục bao trùm "bao gồm" tất cả các trường bắt buộc để thực hiện truy vấn. Nói cách khác, khi tất cả các trường trong một truy vấn được bao phủ bởi một chỉ mục, thì một chỉ mục bao phủ đang được sử dụng. Ví dụ cho một truy vấn như vậy:

SELECT id, title FROM demo_table WHERE id = 1;

Chỉ mục bao trùm có thể trông giống như sau:

INDEX index_name(id, title);

Nếu bạn muốn đảm bảo rằng truy vấn sử dụng chỉ mục bao hàm, hãy đưa ra câu lệnh GIẢI THÍCH trên đó, sau đó xem cột Thêm. Ví dụ:nếu bảng của bạn có chỉ mục đa cột trên id và tiêu đề và truy vấn chỉ truy cập hai cột này được thực thi, MySQL sẽ sử dụng chỉ mục:

mysql> EXPLAIN SELECT id, title FROM demo_table \G;

*************************** 1. row ***************************

<...>

type: index

key: index_name

key_len: 5

rows: 1000

Extra: Using index

<...>

Hãy nhớ rằng chỉ mục bao hàm phải lưu trữ các giá trị từ các cột mà nó bao gồm. Điều đó có nghĩa là MySQL chỉ có thể sử dụng các chỉ mục B-Tree để bao gồm các truy vấn vì các loại chỉ mục khác không lưu trữ các giá trị này.

Nhóm, Chỉ mục phụ và Bản số chỉ mục

Khi thảo luận về các chỉ mục, bạn cũng có thể nghe thấy các thuật ngữ được phân nhóm, chỉ mục phụ và số lượng chỉ mục. Nói một cách đơn giản, chỉ mục được phân cụm là một cách tiếp cận để lưu trữ dữ liệu và tất cả các chỉ mục khác với chỉ mục được phân cụm đều là chỉ mục thứ cấp. Mặt khác, số lượng chỉ mục là số lượng các giá trị duy nhất trong một chỉ mục.

Chỉ mục theo nhóm tăng tốc độ truy vấn vì các giá trị gần nhau cũng được lưu trữ gần nhau trên đĩa, nhưng đó cũng là lý do tại sao bạn chỉ có thể có một chỉ mục được nhóm trong bảng.

Chỉ mục phụ là bất kỳ chỉ mục nào không phải là chỉ mục chính. Một chỉ mục như vậy có thể có các bản sao.

Hạn chế của việc sử dụng chỉ mục

Việc sử dụng chỉ mục chắc chắn có những mặt lợi, nhưng chúng ta không được quên rằng chỉ mục cũng có thể là một trong những nguyên nhân hàng đầu gây ra sự cố trong MySQL. Một số hạn chế của việc sử dụng chỉ mục như sau:

  • Các chỉ mục có thể làm giảm hiệu suất của các truy vấn nhất định - mặc dù các chỉ mục có xu hướng tăng tốc hiệu suất của các truy vấn CHỌN, chúng làm chậm hiệu suất của các truy vấn CHÈN, CẬP NHẬT và XÓA vì khi dữ liệu được cập nhật, chỉ mục cũng cần được cập nhật cùng với nó:bất kỳ hoạt động nào liên quan đến thao tác chỉ mục sẽ chậm hơn bình thường;
  • Các chỉ mục tiêu tốn dung lượng đĩa - một chỉ mục chiếm không gian riêng của nó, vì vậy dữ liệu được lập chỉ mục cũng sẽ sử dụng nhiều dung lượng đĩa hơn;
  • Các chỉ mục dự phòng và trùng lặp có thể là một vấn đề - MySQL cho phép bạn tạo các chỉ mục trùng lặp trên một cột và nó không “bảo vệ bạn” khỏi việc làm như vậy. Hãy xem ví dụ sau:
    CREATE TABLE `demo_table` (
    
    `id` INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    
    `column_2` VARCHAR(10) NOT NULL,
    
    `column_3` VARCHAR(10) NOT NULL,
    
    INDEX(id),
    
    UNIQUE(id)
    
    );

Người dùng thiếu kinh nghiệm có thể nghĩ rằng truy vấn này làm cho cột id tự động tăng lên, sau đó thêm chỉ mục trên cột và làm cho cột không chấp nhận các giá trị trùng lặp. Tuy nhiên, đây không phải là những gì đang xảy ra ở đây. Trong trường hợp này, cùng một cột có ba chỉ mục trên đó:một INDEX thông thường và vì MySQL triển khai cả ràng buộc CHÍNH và DUY NHẤT với các chỉ mục, điều đó sẽ thêm hai chỉ mục nữa trên cùng một cột!

Kết luận

Để kết luận, các chỉ mục trong MySQL có vị trí riêng của chúng - các chỉ mục có thể được sử dụng trong vô số tình huống, nhưng mỗi tình huống sử dụng đó đều có những nhược điểm riêng mà chúng phải được xem xét để tận dụng tối đa chỉ mục đang được sử dụng.

Để sử dụng tốt các chỉ mục, hãy lập hồ sơ truy vấn của bạn, xem xét những tùy chọn bạn có khi nói đến chỉ mục, biết lợi ích và bất lợi của chúng, quyết định chỉ mục nào bạn cần dựa trên yêu cầu của bạn và sau khi bạn lập chỉ mục các cột, hãy đảm bảo rằng các chỉ mục của bạn thực sự được sử dụng bởi MySQL. Nếu bạn đã lập chỉ mục lược đồ của mình đúng cách, hiệu suất của các truy vấn sẽ được cải thiện, nhưng nếu thời gian phản hồi không làm bạn hài lòng, hãy xem liệu có thể tạo chỉ mục tốt hơn để cải thiện nó hay không.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 2 cách nối chuỗi và số trong MariaDB

  2. MariaDB CHARACTER_LENGTH () Giải thích

  3. 4 Hàm trả về số phút từ một giá trị thời gian trong MariaDB

  4. HIỂN THỊ BẢNG BIỂU trong MariaDB

  5. Bạn biết bạn muốn:Di chuyển từ Oracle sang MariaDB