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

Chỉ mục toàn văn bản và chỉ mục tổng hợp và cách chúng ảnh hưởng đến truy vấn

Nếu tôi hiểu câu hỏi của bạn, bạn biết rằng MATCH AGAINST sử dụng chỉ mục FULLTEXT của bạn và bạn băn khoăn không biết MySQL sẽ áp dụng phần còn lại của mệnh đề WHERE như thế nào (tức là nó thực hiện quét bảng hay tra cứu được lập chỉ mục).

Đây là những gì tôi đang giả định về bảng của bạn:nó có một KHÓA CHÍNH trên một số cột id và chỉ mục FULLTEXT.

Vì vậy, trước hết, MySQL sẽ không bao giờ sử dụng chỉ mục FULLTEXT cho mệnh đề WHERE của thành phố / tiểu bang. Tại sao? Bởi vì các chỉ mục FULLTEXT chỉ áp dụng với MATCH AGAINST. Xem tại đây trong đoạn văn sau loạt gạch đầu dòng đầu tiên (không phải dấu đầu dòng Mục lục).

CHỈNH SỬA: Trong trường hợp của bạn, giả sử bảng của bạn không chỉ có 10 hàng, MySQL sẽ áp dụng chỉ mục FULLTEXT cho TRẬN ĐẤU CỦA bạn, sau đó quét bảng trên các kết quả đó để áp dụng thành phố / tiểu bang WHERE.

Vậy điều gì sẽ xảy ra nếu bạn thêm chỉ số BTREE vào thành phố và tiểu bang?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

Cũng như MySQL chỉ có thể sử dụng một lập chỉ mục cho truy vấn này vì nó là một lựa chọn đơn giản. Nó sẽ hoặc sử dụng FULLTEXT hoặc BTREE. Lưu ý rằng khi tôi nói một chỉ mục, tôi muốn nói đến một định nghĩa chỉ mục, không phải một cột trong chỉ mục nhiều phần. Anwway, điều này sau đó đặt ra câu hỏi cái nào làm nó sử dụng?

Điều đó phụ thuộc vào bảng phân tích. MySQL sẽ cố gắng ước tính (dựa trên thống kê bảng từ BẢNG TỐI ƯU HÓA cuối cùng) chỉ mục nào sẽ lược bỏ nhiều bản ghi nhất. Nếu thành phố / tiểu bang WHERE đưa bạn xuống 10 bản ghi trong khi TRẬN ĐẤU LẠI chỉ giúp bạn giảm xuống 100, thì MySQL sẽ sử dụng chỉ mục city__state đầu tiên cho thành phố / tiểu bang WHERE và sau đó quét bảng cho TRẬN ĐẤU LẠI.

Mặt khác, nếu MATCH_AGAINST giúp bạn giảm tới 10 bản ghi trong khi thành phố / tiểu bang WHERE chỉ đưa bạn xuống 1000, thì MySQL sẽ áp dụng chỉ mục FULLTEXT đầu tiên và quét bảng cho thành phố và tiểu bang.

Điểm mấu chốt là cardinality của chỉ mục của bạn. Về cơ bản, các giá trị sẽ đi vào chỉ mục của bạn độc đáo đến mức nào? Nếu mọi bản ghi trong bảng của bạn có thành phố được đặt thành Oakland, thì đó không phải là một khóa rất duy nhất và vì vậy có thành phố ='Oakland' không thực sự làm giảm số lượng bản ghi cho bạn nhiều như vậy. Trong trường hợp đó, chúng tôi cho rằng chỉ mục city__state của bạn có số lượng thấp .

Do đó, nếu 90% các từ trong chỉ mục FULLTEXT của bạn là "John", thì điều đó cũng không thực sự giúp bạn nhiều vì những lý do chính xác.

Nếu bạn có đủ khả năng cung cấp không gian và chi phí UPDATE / DELETE / INSERT, tôi khuyên bạn nên thêm chỉ mục BTREE và để MySQL quyết định chỉ mục nào anh ta muốn sử dụng. Theo kinh nghiệm của tôi, anh ấy thường làm rất tốt việc chọn đúng.

Tôi hy vọng trả lời câu hỏi của bạn.

CHỈNH SỬA: Một lưu ý nhỏ là hãy đảm bảo rằng bạn chọn đúng kích thước cho chỉ số BTREE của mình (trong ví dụ của tôi, tôi đã chọn 10 ký tự đầu tiên trong thành phố). Điều này rõ ràng tạo ra một tác động rất lớn đến cardinality. Nếu bạn chọn thành phố (1), thì hiển nhiên bạn sẽ nhận được số lượng thấp hơn nếu bạn chọn thành phố (10).

EDIT2: Kế hoạch truy vấn của MySQL (ước tính) mà chỉ mục lược bỏ nhiều bản ghi nhất là những gì bạn thấy trong GIẢI THÍCH.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các trường dấu thời gian trong django

  2. Cách thêm cột cuối cùng trong bảng mysql

  3. Tạo bảng html với rowspan từ bảng mysql với một truy vấn?

  4. Cách tạo đồ thị và biểu đồ từ cơ sở dữ liệu mysql trong php

  5. MySQL - Làm cách nào để bỏ chia cột thành hàng?