2017-10-09 90 views
0

我有以下查询:MySQL的多个或在WHERE

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; 

我得到的结果我之后,但在查询速度很慢(〜17S)。有没有更好的方法来构造这个查询?城市字段在business_table中编入索引。

+0

你** **可以使用'REGEXP'('b.city REGEXP“波士顿|达拉斯| Seattle''),但会实际上可能会稍微慢一些。它不应该花17秒,你的桌子有多少行? –

+0

〜我的表中有32,000行 – MoreScratch

+0

您是否尝试过将括号放在您的OR列表中;还是你想要“最近来自波士顿...以及其他所有城市的一切”? – Uueerdo

回答

1

传统的索引根本无助于LIKE '%pattern'查询。该索引未被使用,并且您的查询必须对表进行完整的表扫描。

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

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

0

我有一种感觉,你或者是错误的,所以这是我认为将是更好的查询。

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条件之外的所有条件都放在子查询中来强制它,并让外部查询做最后的过滤。

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)