【发布时间】:2010-06-17 16:20:48
【问题描述】:
我在一个 very 大表上有一个 very 简单的 sql select 语句,它是非规范化的。 (根本不是我的设计,我只是在尝试优化,同时试图说服重新设计的所有者)
基本上,语句是这样的:
SELECT FirstName, LastName, FullName, State
FROM Activity
WHERE (FirstName=@name OR LastName=@name OR FullName=@name)
AND State=@state;
现在,FirstName、LastName、FullName 和 State 都被索引为 BTree,但没有前缀 - 整个列都被索引。州列是 2 个字母的州代码。
我的发现是这样的:
- 当@name = 'John Smith' 和@state = '%' 时,搜索速度非常快,并且会立即产生结果。
- 当 @name = 'John Smith' 和 @state = 'FL' 时,搜索需要 5 分钟(通常这意味着 Web 服务超时...)
- 当我删除 FirstName 和 LastName 比较并仅使用 FullName 和 State 时,上述两种情况都非常有效。
- 当我替换 FirstName、LastName、FullName 和 State 搜索,但对每个搜索使用 LIKE 时,它对 @name='John Smith%' 和 @state='%' 的工作速度很快,但对 @name=' 很慢John Smith%' 和 @state='FL'
- 当我搜索 'John Sm%' 和 @state='FL' 时,搜索会立即找到结果
- 当我搜索 'John Smi%' 和 @state='FL' 时,搜索需要 5 分钟。
现在,重申一下 - 表格未标准化。与许多其他用户一样,John Smith 出现了很多次,因为没有引用某种形式的用户/人员表。我不确定单个用户可能出现多少次,但表本身有 9000 万条记录。再说一次,不是我的设计……
我想知道的是——虽然这个设计有很多问题,但是是什么导致了这个特定的问题。
我的猜测是索引树太大了,遍历它们需要很长时间。 (名、姓、全名)
无论如何,我感谢任何人对此的帮助。就像我说的,我正在努力说服他们重新设计,但与此同时,如果有人能帮我找出确切的问题是什么,那就太好了。
更新
根据要求,以下是运行解释后的详细信息:
id: 1, select type: 'SIMPLE', table: 'activity', type: 'ref', possible keys: 'IDX_LastName,IDX_FirstName,IDX_FullName,IDX_State', key: 'IDX_State', key_len: '3', ref: 'const', rows: 7227364, extra: 'Using where'
【问题讨论】:
-
建议您使用 EXPLAIN 查看查询计划。将这些查询的 EXPLAIN 结果添加到您的问题中会非常有用。 INDEX 结构并不是 100% 清楚的。还请包括
SHOW CREATE TABLE Activity\G的输出 -
拥有 9000 万条记录,如果像您说的那样每列都有很多点击量,那么您的时间可能会花在一遍又一遍地合并所有结果上,就像其他人所说的那样,EXPLAIN 是你的朋友