我目前在mysql用户表中有一个名称和姓氏字段,以及一个搜索框,它们可以在其中同时输入,所以我的查询基本上是
SELECT name,surname FROM user
WHERE CONCAT(name,' ',surname) LIKE '@search%'这很好,但是在一个大表上会变得非常慢,即使名称和姓氏列都是索引的,而且当搜索被分割时,它非常快,是否有方法索引连接字段,或者当两个字段都被索引时,它们是否已经被索引,切换到全文索引会更快吗?
发布于 2016-09-08 22:07:40
我是否正确地假设@search被某种东西所取代?
如果您正在搜索“单词”,那么FULLTEXT的工作速度要快得多。但是,要注意它的局限性(停止词、最小字长等)。
这个特殊的尝试,CONCAT(name,' ',surname) LIKE '@search%',只会检查name开头的“@search”,我怀疑这是不是你想要的。你想要什么?
请记住,name LIKE '@search%'比name LIKE '%search%'快得多,因为它可以使用INDEX(name),我假设您使用了INDEX(name)?
如果同时拥有INDEX(name)和INDEX(surname),那么这将是相当快的:
SELECT ...
WHERE name LIKE '@search%'
UNION DISTINCT
SELECT ...
WHERE surname LIKE '@search%';这是因为这两个索引都可以使用。否则,它们不太可能同时被使用;相反,会有一个“表扫描”。(如果您有一个旧版本的OR,那么使用MySQL就不会那么好了。)
但是,如果用户使用'%‘或'_’启动@search,则会显示为“血色”,因为前面的通配符将导致表扫描。
同时,如果您不检查各种特殊字符,您将非常容易受到SQL注入的影响!
澄清后的
由于用户是单独键入名称,所以您可以更容易地测试:
WHERE name LIKE '@name%'
AND surname LIKE '@surname%'然后两者都有(万一用户缩短了其中一个):
INDEX(name, surname)
INDEX(surname, name)这些都比你的好,INDEX(name), INDEX(surname)。
由于数据输入似乎是一个单独的字段,所以使用客户端编程语言将其拆分为@name和@surname。(在SQL中,这是可能的,但很混乱;参见SUBSTRING_INDEX()。)
阅读有关“复合索引”的文章,了解为什么这些索引更好,以及为什么原始CONCAT效率特别低。
发布于 2016-09-10 18:04:23
编辑:这假设您的搜索开始包括的名字,直到完成,继续后面的姓。
只要搜索的左边没有通配符,就可以将您的名称和姓氏字段作为一个索引进行索引,如MySQL手册中对多列索引的参考:http://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html
然后,让我们强制查询使用多个col索引。这些步骤是:
1.)创建索引
CREATE INDEX fullname ON table_name (name, surname)2.)使用索引暗示告诉MySQL在查询中使用您的多列索引
SELECT name,surname FROM user USE INDEX (fullname) WHERE CONCAT(name,' ',surname) LIKE '@search%'当进行类似的比较时,只要搜索开始时没有通配符'%‘,它就会使用从左到右的索引。
最好的选择就是将您的字段更改为全文,并利用MYSQL的新全文搜索功能。下面是MySQL站点中的一个很好的例子,展示了这种搜索实现起来是多么容易:http://dev.mysql.com/doc/refman/5.7/en/fulltext-query-expansion.html
https://stackoverflow.com/questions/39389722
复制相似问题