MySQL MATCH对抗JOIN非常慢

时间:2015-11-24 13:59:54

标签: mysql performance

和很多其他人一样,我的查询也很慢。我已经阅读了几个关于这个问题的帖子,但没有一个能解决我的问题。

我需要加入和搜索两个tabeles .1表是一个订单表,另一个是帐户表。两个myisam引擎。

orders

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

accounts

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

两个表格都有大约400.000条记录,实际上它们有更多列。 idaccount_id列上还有索引。 remark列为FULLTEXT

现在,我想执行查询以查找accounts.remarkorders.remark包含文字hello的所有订单。

首先,我为此查询使用了一个简单的LIKE语句。哪个足够快,因为没有那么多订单。你使用了这个查询:

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

现在我想用MATCH AGAINST加快查询速度,这应该快得多。所以我将上面的查询更改为:

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

如您所见,MATCH AGAINST甚至比LIKE版本慢。当我在WHERE子句中删除其中一个MATCH时,它超级快!

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

因此,当匹配多个表时,查询变得非常慢。我该怎么做才能加快速度呢?

提前致谢!

1 个答案:

答案 0 :(得分:3)

OR的常用方法是将它们转换为UNION(MySQL有时会隐式执行,但在这种情况下不会):

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)