2017-06-21 80 views
0

目前,我有这个疑问如何优化与通配符查询WHERE与LIMIT子句

SELECT field1 FROM table1 
WHERE field1 LIKE '%foo%' 
LIMIT 20 

它是更有效的有以下查询?

SELECT field1 FROM table1 
WHERE 
field1 LIKE 'foo' OR 
field1 LIKE 'foo%' OR 
field1 LIKE '%foo%' 
LIMIT 20 

版本的SQL(对不起,我应该早点mentionned)一个共享的主机

的MySQL 5.5 InnoDB引擎。有了这个配置我不能使用FULLTEXT指数(全文索引可从MySQL的InnoDB的V5.6)

MY具体目的

我需要找到20条记录包含。大多数时候,这个词将匹配在场上完全值,即见下表:

| **field1** | **search** | 
| record1 | foo  | 
| record2 | fooziness | 
| record3 | other1 | 
| record4 | foo  | 
| record5 | other2 | 
|  ...  |  ...  | 

我知道'word' OR 'word%'使用INDEX而最后'%word%'没有。

将查询优化器首先尝试找到'word' OR 'word%'记录并保存低效搜索'%word%'如果20 'word'被发现?

+1

为什么你不测试它并检查解释计划? [** MySQL **](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) –

+1

btw你的第二个查询不是好的。您必须编写'field1 ='foo'或field1 LIKE'foo%'或field1 LIKE'%foo%' –

+0

我还没有足够的数据在表中:-) – gentleboy

回答

3

这对您来说测试要比我们回答容易得多 - 尤其是因为实际查询可能比您显示的要复杂得多。

但是......

按照manual,限制可以优化查询,但主要是通过订单时。这是有道理的,因为很可能会有多个“where”子句和限制子句不一定知道哪些子句受限制子句的影响。

我已经通过执行以下操作以类似的查询被骗:

(SELECT field1, 1 as quality FROM table1 
    WHERE field1 = 'foo' 
) union 
(SELECT field1, 2 as quality FROM table1 
    WHERE field1 LIKE 'foo%' 
) union 
(SELECT field1, 3 as quality FROM table1 
    WHERE field1 LIKE '%foo%' 
)  
order by quality 
LIMIT 20 

这是可读的要少得多,但没有欺骗优化器放弃查询,一旦发现了20条记录。不知道这是否可行。

当然,如果性能对您很重要,那么使用MySQL Full text searching要快得多,而且要脆弱得多。

+0

你是对的,查询对于许多联接而言更复杂。不能使用全文索引作为与innoDB的MySQL 5.5(抱歉没有提到)。 – gentleboy

+0

我认为一个简单的改变就可以做到这一点,但它似乎更复杂。我测试过,现在看来你有唯一的解决方案。我想我必须尽快重写我的查询。 – gentleboy

+0

我添加了parens,这样'ORDER BY'和'LIMIT'将应用于'UNION',而不是最后一个'SELECT'。 –