【发布时间】:2012-01-24 10:40:15
【问题描述】:
我遇到了一个小问题,非常感谢您的帮助。
我有一个包含 33,000,000 行的 MyISAM 表,其数据结构如下:
id -> Primary Key, Unsigned INT, Auto-Increment
characters -> Unique Indexed, varchar(15)
price -> decimal (10,2)
active -> tinyint(1)
我编写了一个脚本,该脚本从用户那里获取搜索值,然后根据用户输入“Kevin”创建以下查询:
SELECT characters, price
FROM listings_dvla
WHERE active=TRUE
AND LOWER(REPLACE(characters, ' ', '')) 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]*'
ORDER BY characters ASC
LIMIT 0, 12
只是为了解释一下,正则表达式只是试图按顺序匹配每个字母,或者在“车牌语言”中表示相同的字母序列,例如。 N == 1V
问题是,这个查询需要该死的时间! 20+秒。我已经阅读了相当多的内容,发现将字符作为主键比较慢,所以我把它拿出来并添加了一个 ID 字段。我使用了 EXPLAIN 来显示索引并且它们为 NULL,我认为这是因为 REGEXP 禁用了它们(我也在某处读过)。
我的问题是,有没有人有任何好主意来大幅提高查询性能?因为我觉得我没有意识到让这个速度更快的非常关键的事情。
如果需要,我会更改表结构,所以不要担心给我一个相当极端的答案。
感谢阅读本文,如有任何建议,将不胜感激。
【问题讨论】:
-
如果您删除字符列上的 LOWER 和 REPLACE ,时间是否会有所不同?通常,您希望避免对 where 子句中的列执行字符串操作,因为不太可能使用索引。还可以使用直接的 `characters = 'kevin' 或完全匹配的东西进行测试。您最好在代码中调整用户输入,而不是运行多个查询而不是一个执行正则表达式匹配并操作您搜索的列的查询。
标签: mysql performance search full-text-search