1

我有一个相对较大的表(5,208,387 行,400mb 数据/670mb 索引),我用来搜索的所有列都是索引。 name并且type是 VARCHAR(255) BTREE INDEX 并且sdate是包含时间戳的 INTEGER 列。

我无法理解一些问题,首先这个查询很慢(5秒):

SELECT *
FROM `mytable`
WHERE `name`  LIKE 'hello%my%big%text%thing%'
AND `type` LIKE '%'
ORDER BY `sdate` DESC LIMIT 3

解释以上内容:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE      mytable range   name        name    257 NULL    5191    Using where

虽然这个速度非常快(5 毫秒):

SELECT *
FROM `mytable`
WHERE `name`  LIKE 'hello.my%big%text%thing%'
AND `type` LIKE '%'
ORDER BY `sdate` DESC LIMIT 3

解释以上内容:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE      mytable range   name        name    257 NULL    204 Using where

由于索引,扫描的行数不同是有意义的,但是拥有 5k 个索引行需要 5 秒似乎太多了。

此外,排序name而不是sdate使查询非常快,但我需要按时间戳排序。

我不明白的第二件事是,在将最后一列添加到索引之前,数据库的索引为 1.4GB,而不是在运行 OPTIMIZE/REPAIR 之后,大小仅为 670MB。

4

1 回答 1

1

问题是,只有第一个之前%的部分可以利用索引,其余的like字符串需要处理所有匹配hello%hello.my%没有帮助的行。此外,按另一列排序然后使用索引,可能需要第二遍,或者至少是扫描而不是已经排序的索引。获得更好性能的选项(可以彼此独立实施)是:

  1. 在 name 列上使用全文索引并使用MATCH() AGAINST()搜索而不是LIKE使用%'s。
  2. 添加sdateto in 索引combined (name,sdate)可以很好地加速排序。
于 2012-06-27T14:16:48.133 回答