Mysql
將 MATCH…AGAINST 部分移動到查詢的不同部分(例如,在評估 JOIN 之前)會提高性能嗎?
基本上,我有以下查詢:
select `t`.* from `tracking` `t` where exists ( select `ti`.`id` from `tracking_items` `ti` inner join `cars` `c` on (`c`.`car_id` = `ti`.`tracking_object_id`) where `t`.`id` = `ti`.`tracking_id` and match(`c`.`car_text`) against('+bulgaria +turkey' in boolean mode) limit 1 ) and ... limit 5
我遇到的問題?
列有
FULLTEXT
索引c.car_text
,但是查詢執行有點慢(特別是對於很少出現的記錄,例如搜尋不存在的關鍵字)。我還沒有公佈 的結果
EXPLAIN
,因為我想知道我的問題背後的理論,例如針對不同的可能情況。我使用帶有 InnoDB 儲存引擎的 MySQL 5.6,值得一提的是,該
cars
表有大約 1.6 億條記錄。
我很高興你來到這裡。我一直建議使用 FULLTEXT 索引先收集鍵,然後將其連接到其他表。
Oct 25, 2011
:在 BOOLEAN MODE 中忽略 FULLTEXT 索引,條件為“字數”Jul 18, 2012
:為什麼全文搜尋返回的行數少於 LIKEMay 07, 2012
:MySQL EXPLAIN 不顯示 FULLTEXT 的“使用索引”Jan 29, 2012
:Mysql全文搜尋my.cnf優化Aug 01, 2016
:如何使用 ORDER BY 快速進行 FULLTEXT 搜尋?在您的特定情況下,我建議將您的查詢重寫為全面連接:
SELECT t.* FROM tracking t INNER JOIN tracking_items ti ON t.id = ti.tracking_id INNER JOIN (SELECT car_id,car_text FROM cars WHERE MATCH(car_text) AGAINST ('+bulgaria +turkey' in boolean mode)) c ON ti.tracking_object_id = c.car_id LIMIT 5;
或許
SELECT t.* FROM (SELECT car_id,car_text FROM cars WHERE MATCH(car_text) AGAINST ('+bulgaria +turkey' in boolean mode)) c INNER JOIN tracking_items ti ON c.car_id = ti.tracking_object_id INNER JOIN tracking t ON ti.tracking_id = t.id LIMIT 5;
如果這些查詢為您提供了一個想法,如果您仍想使用
WHERE EXISTS
.請對這些查詢和您的查詢執行解釋計劃並查看差異
EXPLAIN select `t`.* from `tracking` `t` where exists ( select `ti`.`id` from `tracking_items` `ti` inner join `cars` `c` on (`c`.`car_id` = `ti`.`tracking_object_id`) where `t`.`id` = `ti`.`tracking_id` and match(`c`.`car_text`) against('+bulgaria +turkey' in boolean mode) limit 1 ) and ... limit 5; EXPLAIN SELECT t.* FROM (SELECT car_id,car_text FROM cars WHERE MATCH(car_text) AGAINST ('+bulgaria +turkey' in boolean mode)) c INNER JOIN tracking_items ti ON c.car_id = ti.tracking_object_id INNER JOIN tracking t ON ti.tracking_id = t.id LIMIT 5; EXPLAIN SELECT t.* FROM tracking t INNER JOIN tracking_items ti ON t.id = ti.tracking_id INNER JOIN (SELECT car_id,car_text FROM cars WHERE MATCH(car_text) AGAINST ('+bulgaria +turkey' in boolean mode)) c ON ti.tracking_object_id = c.car_id LIMIT 5;
試一試,讓我們知道會發生什麼!!!