MySQL中的MySQL多个OR

时间:2017-10-09 23:10:05

标签: mysql full-text-search query-optimization

我有以下查询:

SELECT
    b.business_name,
    b.address,
    b.city,
    b.state,
    b.phone_number,
    i.date
FROM business_table b
LEFT JOIN inspection_table i ON b.id = i.business_id
WHERE i.date = (
    SELECT MAX(i.date)
    FROM inspection_table i
    WHERE b.id = i.business_id
)
AND b.city LIKE '%Boston%'
OR b.city LIKE '%Dallas%'
OR b.city LIKE '%Seattle%'
OR b.city LIKE '%New York%'
OR b.city LIKE '%Portland%'
OR b.city LIKE '%San Antonio%'
OR b.city LIKE '%Los Angeles%'
OR b.city LIKE '%Miami%'
ORDER BY i.date DESC;

我得到了我的结果,但查询非常慢(~17秒)。有没有更好的方法来构建此查询? city字段在business_table中编制索引。

3 个答案:

答案 0 :(得分:1)

传统索引根本不会帮助LIKE '%pattern'查询。未使用索引,您的查询必须对表进行完整的表扫描。

如果您希望使用MySQL有效搜索,则需要使用Full-Text Search Functions

您可能喜欢我的演示文稿Full Text Search Throwdown,其中我比较了不同的MySQL文本搜索方法。

答案 1 :(得分:0)

我觉得你的OR是错的,所以这就是我认为将是更好的查询。

SELECT
    b.business_name,
    b.address,
    b.city,
    b.state,
    b.phone_number,
    li.lastInspection AS `date`
FROM (SELECT business_id, MAX(i.date) as lastInspection
      FROM inspection_table
      GROUP BY business_id) AS li
INNER JOIN business_table b
ON li.business_id = b.business_id
WHERE b.city LIKE '%Boston%'
   OR b.city LIKE '%Dallas%'
   OR b.city LIKE '%Seattle%'
   OR b.city LIKE '%New York%'
   OR b.city LIKE '%Portland%'
   OR b.city LIKE '%San Antonio%'
   OR b.city LIKE '%Los Angeles%'
   OR b.city LIKE '%Miami%'
ORDER BY li.lastInspection DESC
;

如果您有巨大数量的城市或企业,此可能会变慢;但我打赌inspection_table (business_id, date)上的索引会加快它的速度。

理想情况下,这将获得您的上次检查,找到他们的业务,然后过滤业务;如果不是,你可以通过将除WHERE条件之外的所有条件放在子查询中来强制它,并让外部查询进行最终过滤。

答案 2 :(得分:0)

查询的制定似乎存在多个问题。其他答案带来了一些修复。我会尝试解决所有问题。

括号是必须的 - x AND y OR z OR w被视为(x AND y) OR z OR w。这可能会修复意图和性能。

您正在寻找South Boston以及Boston?还Boston Heights?如果没有,那么摆脱通配符(%)。这样就可以索引city

如果你需要外卡,那么使用FULLTEXT索引和MATCH...AGAINST...将会运行得更快。

我认为,使用前导%,REGEXP建议黑曜石年龄会更快,因为它只会进行city的一次扫描。

如果business_id不是PRIMARY KEY,请添加以下内容:

INDEX(business_id, date)
INDEX(business_id, city)