使用正则表达式加快mysql查询并按长度排序

时间:2014-02-06 04:55:54

标签: mysql regex

我正在尝试在我的网站上实施搜索自动完成功能。到目前为止我想出的只是一个包含搜索词(城市)的表格

city_id int(10) Auto Increment, Primary
city_name varchar(200) Index

和查询

select * from city_names where lower(city_name) like lower('my_search_term%) order by length(city_name) limit 10;

此查询返回10个包含搜索字符串的最短名称的城市,正是我需要的,但速度非常慢。我的猜测是数据库首先搜索与正则表达式匹配的所有内容,然后按长度对结果进行排序,然后选择10行。我认为最好以某种方式按长度(city_name)对数据进行预排序,以便查询在达到与正则表达式匹配的10行后停止。

所以我的问题是:

  1. 有没有办法按内容长度对city_names列进行排序(整理?)?我不打算改变表数据,因此需要对数据进行一次排序。
  2. 哪个数据库引擎和索引结构适合此表(city_names数据不唯一)?
  3. 有没有办法更改我的查询以提高性能?
  4. 欢迎任何想法。

    更新: 基于zerkms's suggestions,我做了以下内容:

    1. 将整理更改为latin_general_ci。这使我摆脱了LOWER(city_name)的转换。
    2. 创建另一列(sort_index)并使用按长度排序(city_name)和city_name的增量值填充它。即,短名称首先出现,“A **”出现在“B **”之前,对于长度相同的城市。现在搜索速度更快。
    3. 将默认订单更改为sort_index升序。现在我在查询中不需要任何ORDER命令。
    4. 表和查询现在看起来像:

      sort_index int(10) Primary
      city_name varchar(200)
      city_id int(10) Auto Increment
      
      select * from city_names where city_name like lower('my_search_term%) limit 10;
      

1 个答案:

答案 0 :(得分:3)

  1. 如果使用*_ci排序规则,则字符串比较应不区分大小写。所以应该使用city_name LIKE LOWER('term%')
  2. 创建另一列并在其中存储每个city_name列长度
  3. 创建复合(city_name, city_name_length)索引(但有可能不会使用city_name_length