如何使这个SQL不可思议?

时间:2014-02-17 12:18:41

标签: mysql

我使用了一个在线工具来分析我的一个sql查询(The Query花了我很多年的时间)。

我的查询接受一个单词(在这个例子中,单词是'dog。')并尝试在'qa'表中找到它,当它加入来自登录表的行数据时,login.pid === qa.u

SELECT login.pid,login.name, 
qa.id,qa.end,qa.react,qa.win,qa.stock,qa.num,qa.ratio,qa.u,qa.t,qa.k,qa.swipes,qa.d 
FROM login,qa WHERE login.pid=qa.u AND (qa.k LIKE '%dog.%' OR qa.k='.dog.') 
ORDER BY qa.d DESC LIMIT 0,15

我理解该工具告诉我的内容:

Argument with leading wildcard
An argument has a leading wildcard character, such as "%foo". The predicate with 
this argument is not sargable and cannot use an index if one exists.

但我不知道如何在'()'中使用索引而不损坏或更改结果......有人可以解释一下如何在查询条件中使用索引吗?

我认为如果这是不可苛刻的,那么结果会更快?

1 个答案:

答案 0 :(得分:0)

首先,学习使用现代join语法:

SELECT login.pid, login.name, 
       qa.id, qa.end, qa.react, qa.win, qa.stock, qa.num, qa.ratio, qa.u, qa.t,qa.k, qa.swipes, qa.d 
FROM login join
     qa 
     on login.pid = qa.u 
WHERE (qa.k LIKE '%dog.%' OR qa.k = '.dog.') 
ORDER BY qa.d DESC
LIMIT 0,15;

基本上“sargable”意味着你可以使用特定表达式的索引(它不是英文单词,它是首字母缩略词)。 qa.k上的表达式不能使用索引。

这可能没有区别,具体取决于查询的查询计划。例如,如果引擎决定扫描login表,然后在qa中查找值,则索引将无济于事。不过,它有助于走另一条路。

坏消息是你无法在MySQL中使这个表达式变得可思议。好消息是,您可以使用全文索引来执行您想要的操作,甚至更多。你可以阅读它们here。一个小注意事项是默认设置忽略短字,最多三个字母。因此,如果您确实想要搜索“dog”,则需要更改默认设置。

顺便说一句,以下表达式可以使用qa.k上的索引:

WHERE (qa.k LIKE 'dog.%' OR qa.k = '.dog.') 

(我不确定MySQL是否真的会使用索引,因为它有时会被or弄糊涂。)