简体   繁体   中英

MySQL MATCH AGAINST over JOIN very slow

As a lot of other people, I also have a very slow query. I have read several posts about this issue, but none does solve my problem.

I heb two tabeles that need to be joined and searched in. 1 table is a orders table, and the other one is a accounts tabel. Both myisam engine.

Table orders :

id  |  account_id  | remark | datetime
--------------------------------------------------
1   |  1           | hello  | 2015-11-24 12:05:01

Table accounts

id  | firstname | lastname | remark 
------------------------------------
1   | John      | Doe      | hello

Both tabels have about 400.000 records an in real they have some more columns. There are also indexes on the id and account_id columns. The remark columns are FULLTEXT

Now I want to perform a query to find all orders where the accounts.remark or orders.remark contains te text hello .

First, I used a simple LIKE statement for this query. Which was fast enough because there where not so much orders. U used this query:

SELECT SQL_NO_CACHE
  orders.id AS orderID,
  accounts.id AS accountID
FROM
  orders
  JOIN accounts ON orders.account_id = accounts.id
WHERE
  orders.remark LIKE '%hello%' OR
  accounts.remark LIKE '%hello%'

Runtime: 1.66 seconds

Now I wanted to speed this query up with MATCH AGAINST , which should be a lot faster. So I changed the query above to:

SELECT SQL_NO_CACHE
  orders.id AS orderID,
  accounts.id AS accountID
FROM
  orders
  JOIN accounts ON orders.account_id = accounts.id
WHERE
  MATCH(orders.remark) AGAINST('+hello' IN BOOLEAN MODE) OR
  MATCH(account.remark) AGAINST('+hello' IN BOOLEAN MODE)

Runtime: 1.84 seconds

As you can see, the MATCH AGAINST is even slower than the LIKE version. When I remove one of the MATCH against lines in the WHERE clause, it's super fast!

SELECT SQL_NO_CACHE orders.id AS orderID, accounts.id AS accountID
FROM orders
JOIN accounts ON orders.account_id = accounts.id
WHERE MATCH(orders.remark) AGAINST('+hello' IN BOOLEAN MODE)

Runtime: 0.0018 seconds

So, the query get's very slow when matching over multiple tables. What can I do to speed this up?

Thanks in advance!

The usual approach with OR's is to convert them to a UNION (MySQL sometimes does it implicitly, but not in this case):

SELECT
  orders.id AS orderID,
  accounts.id AS accountID
FROM
  orders
  JOIN accounts ON orders.account_id = accounts.id
WHERE
  MATCH(orders.remark) AGAINST('+hello' IN BOOLEAN MODE)
UNION
SELECT
  orders.id AS orderID,
  accounts.id AS accountID
FROM
  orders
  JOIN accounts ON orders.account_id = accounts.id
WHERE
  MATCH(account.remark) AGAINST('+hello' IN BOOLEAN MODE)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM