表中有两个name
列。(name 1,name 2)
我希望接收关键字作为输入,并在包括关键字的数据中以最相似的顺序输出它们。
如果用户输入ed
,我们希望输出的顺序是“ed”、“Ed Sheeran”和“Ahmedzidan”。(“Ed Sheeran”和“Ahmed Zidan”的顺序可能会根据匹配方法而变化。)
我们希望单词“艾德”是最相似的,并且紧随其后的是单词“ed”。
我不知道怎么做精确匹配。
即使上面的'艾德'包含在name 1或name 2中,也会对其进行搜索。两者之间没有优先级。
我现在使用的方法:
select
((LENGTH(name1) - LENGTH(( 'ed')))) + ((LENGTH(name) - LENGTH(( 'ed')))
) as score
from user
where name like '%ed%' or name2 like '%ed%'
order by score asc
另一个道:
select
(CASE WHEN name1 = 'ed' or name2 = 'ed' THEN 4
WHEN name1 like 'ed%' or name2 like 'ed%' THEN 3
WHEN name1 like '%ed' or name2 like '%ed' THEN 2
WHEN name1 like '%ed%' or name2 like '%ed%' THEN 1
END
)
as score
from user
where name like '%ed%' or name2 like '%ed%'
order by score desc
但是,两个结果都和我想的不一样,我不知道哪一个更快。
我试过使用full-text index
,但是它似乎需要太多的牺牲(?)来搜索一个字母表。而且当用户输入长单词的关键字时,它太慢了。
示例:关键字:艾德-〉0.2s,关键字:艾德·希兰-〉5秒。
最好的办法是什么?
如果以上两种方法是最好的,那么哪一种更快?
2条答案
按热度按时间vpfxa7rd1#
让我来讨论一下查询的每个部分对性能的影响:
WHERE
有OR
和LIKE
,前面有一个通配符,每个通配符都强制查询进行完全扫描,检查每一行。1.我不需要进一步讨论;所有其他方面(包括冗长的
CASE
)在判断速度时都不那么重要。如果表很大(并且不能缓存到RAM中),那么这将有助于一些:这里的技巧是将表扫描更改为索引扫描。
所有工作都在RAM的“buffer_pool”中完成。当表大于RAM时,查询需要查看所有行,处理必须从buffer_pool中取出内容,以便从磁盘加载数据。I/O可能是影响性能的最大因素。
表的BTree包含所有行的所有列。上面提到的INDEX包含name 1、name 2和组成
PRIMARY KEY
的任何列的每一行。也就是说,索引可能比表小。因此,索引可能位于RAM中,而数据必须分页输入。(这与I/O有关。)pcww981p2#
我认为你可以使用POSITION函数并按它排序。没有必要这样使用选择CASE,因为在你的查询中没有这样的逻辑运算和重复的LIKE函数,那会浪费很多时间。使用POSITION函数,你可以得到你想要的结果,如果你只是想先点“Ed Sharon”,然后点其他“ed”,比如“Mr. Bambang Ed”。