我使用了一个在线工具来分析我的一个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.
但我不知道如何在'()'中使用索引而不损坏或更改结果......有人可以解释一下如何在查询条件中使用索引吗?
我认为如果这是不可苛刻的,那么结果会更快?
答案 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
弄糊涂。)