我有以下查询:
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中编制索引。
答案 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)