Câu trả lời của @Alden Quimby là đúng khi nó đi, nhưng câu chuyện còn nhiều điều hơn thế, bởi vì MySQL sẽ chỉ thử để chọn chỉ mục tối ưu và khả năng đưa ra quyết định đó bị hạn chế do cách các chỉ mục toàn văn bản tương tác với trình tối ưu hóa.
Điều thực sự xảy ra là:
Nếu user_id được chỉ định tồn tại trong 0 hoặc 1 hàng phù hợp trong bảng, trình tối ưu hóa sẽ nhận ra điều này và sẽ chọn user_id làm chỉ mục cho truy vấn đó. Thực hiện nhanh chóng.
Nếu không, trình tối ưu hóa sẽ chọn chỉ mục toàn văn bản, lọc mọi hàng phù hợp với chỉ mục văn bản đầy đủ để loại bỏ các hàng không chứa user_id khớp với mệnh đề WHERE. Không nhanh bằng.
Vì vậy, nó không thực sự là con đường "tối ưu". Nó giống như toàn văn bản hơn, với một tối ưu hóa tốt để tránh tìm kiếm toàn văn bản với một điều kiện mà chúng tôi biết rằng chúng tôi hầu như không quan tâm đến bảng.
Lý do điều này bị hỏng là chỉ mục toàn văn bản không cung cấp bất kỳ số liệu thống kê có ý nghĩa nào trở lại trình tối ưu hóa. Nó chỉ nói "vâng, tôi nghĩ rằng truy vấn đó có lẽ chỉ nên yêu cầu tôi kiểm tra 1 hàng" ... điều này tất nhiên làm hài lòng trình tối ưu hóa rất nhiều, vì vậy chỉ mục toàn văn sẽ thắng giá thầu với chi phí thấp nhất, trừ khi chỉ mục có số nguyên giá trị cũng tương đối thấp hoặc thấp hơn.
Tuy nhiên, điều đó không có nghĩa là tôi sẽ không thử theo cách này trước.
Có một tùy chọn khác, sẽ hoạt động tốt nhất với các truy vấn đầy đủ văn bản IN BOOLEAN MODE
và đó là tạo một cột khác mà bạn sẽ điền vào một cái gì đó như CONCAT ('user_id _', user_id) hoặc một cái gì đó tương tự, rồi khai báo chỉ mục văn bản đầy đủ 2 cột.
filter_string VARCHAR(48) # populated with CONCAT('user_id_',user_id);
....
FULLTEXT KEY (message,filter_string)
Sau đó, chỉ định mọi thứ trong truy vấn.
SELECT ...
WHERE user_id = 500 AND
MATCH (message,filter_string) AGAINST ('+kittens +puppies +user_id_500' IN BOOLEAN MODE);
Bây giờ, chỉ mục toàn văn bản sẽ chỉ chịu trách nhiệm đối sánh những hàng có mèo con, chó con và "user_id_500" xuất hiện trong chỉ mục văn bản đầy đủ kết hợp của hai cột, nhưng bạn vẫn muốn có bộ lọc số nguyên ở đó để đảm bảo kết quả cuối cùng bị hạn chế mặc dù có bất kỳ sự xuất hiện ngẫu nhiên nào của "user_id_500" trong thông báo.