MySQL numberplate相关搜索性能?
我有点小问题,非常感谢您的帮助 我有一个MyISAM表,其中包含33000000行,数据结构如下:MySQL numberplate相关搜索性能?,mysql,performance,search,full-text-search,Mysql,Performance,Search,Full Text Search,我有点小问题,非常感谢您的帮助 我有一个MyISAM表,其中包含33000000行,数据结构如下: id -> Primary Key, Unsigned INT, Auto-Increment characters -> Unique Indexed, varchar(15) price -> decimal (10,2) active -> tinyint(1) 我编写了一个脚本,从用户那里获取搜索值,然后根据用户键入的“Kevin”创建以下查询: 只是为了解释一下
id -> Primary Key, Unsigned INT, Auto-Increment
characters -> Unique Indexed, varchar(15)
price -> decimal (10,2)
active -> tinyint(1)
我编写了一个脚本,从用户那里获取搜索值,然后根据用户键入的“Kevin”创建以下查询:
只是为了解释一下,regexp只是试图按顺序匹配每个字母,或者是在“车牌语言”中表示相同意思的字母序列,例如N==1V
问题是,这个问题需要很长时间!20多秒。我已经阅读了相当多的内容,发现将字符作为主键的速度较慢,所以我将其取出并添加了一个ID字段。我使用了EXPLAIN来显示索引,它们是空的,我假设这是因为REGEXP禁用了它们(我在某处也读到了)
我的问题是,有没有人有什么好主意来大幅提高性能?因为我觉得我没有意识到一些非常关键的事情,让这变得更快
如果需要的话,我会改变表格结构,所以不要担心给我一个非常极端的答案
感谢阅读本文,如有任何建议,将不胜感激。mysql中的字符串查询速度非常慢。我甚至不确定是否有任何键(除了
FULLTEXT
对它们适用)
您在where条件下使用函数,这意味着必须加载每条记录,使用replace和lower进行更新,并与regexp进行比较(mysql无法提前知道结果会是什么)
基本上:使用这种regexp,您永远不会很快得到这个查询
但是,您可以添加字段,例如isWord TINYINT DEFAULT 0
(带索引)并使用查询:
updatelistings\u dvla SET isWord=1,其中active=TRUE
和下部(替换(字符,,'')REGEXP'^[a-z0-9]*[(k)]+[a-z0-9]?[(e)(3)]+[a-z0-9]?[(v)]+[a-z0-9]?[(i)(1)]+[a-z0-9]?[(n)(11)(1v)]+[a-z0-9]*'
然后,按*索引字段选择记录,并使用:select。。。哪里isWord=1
首先,您可以“清理”字符字段,这样就不必将其转换为小写并去掉空格。这个动作几乎肯定意味着你失去了任何索引的好处
其次,明显的替代方法是在客户端上运行将“kevin”修改为各种数字板形式的代码,并将其转换为“in”查询:
如果您还希望能够搜索字符中的单词,例如,为参数KEV返回10 KEV,您可以通过创建带有子字符串的附加列来进行一些欺骗
表1\u dvla
ID characters cleaned_characters characters_right7 characters_right6 characters_right5 characters_right4 characters_right3
1 A10 KEV a10kev 10kev 0kev kev
2 KT 11 TCP kt11tcp t11tcp 11tcp 1tcp tcp
脏,但通过在所有列上创建索引,您应该能够获得非常快速的查询。Insert/update会比较慢,不过…因为您没有在where子句中使用ID字段,所以mysql没有使用您的主键。这并不奇怪
我想,您需要的是字符列上的全文索引。如果删除字符列上的下一个并替换,时间是否会有所不同?通常,您希望避免对where子句中的列执行字符串操作,因为不太可能使用索引。也可以直接用“characters=”kevin“或完全匹配的东西进行测试。您最好在代码中调整用户输入,而不是运行多个查询,而不是运行一个与regexp匹配并处理您搜索的列的查询。假设我搜索了“kev”,您的查询将无法找到编号为“10 kev”的查询。搜索一个精确的似乎非常快,只有在我尝试使用LIKE或REGEXP时,它才会减慢速度。啊,对了-没有足够详细地查看REGEXP来获取它。LIKE和REGEXP几乎肯定不会使用索引;已经修改了答案,以显示如何解决此问题。但是需要首先运行更新查询,因此这将花费与正常搜索相同的时间?还是我在这里误解了你?@Kevinorris是的,首先需要20多秒,但我无法想象它工作得更快
select *
from listings_dvla
where active = 1
and cleaned_characters in ('kev1n', 'kev1iv'.....)
ID characters cleaned_characters characters_right7 characters_right6 characters_right5 characters_right4 characters_right3
1 A10 KEV a10kev 10kev 0kev kev
2 KT 11 TCP kt11tcp t11tcp 11tcp 1tcp tcp