需要在AND语句中索引列吗?

时间:2011-02-17 21:29:55

标签: sql mysql indexing query-optimization

我必须在这样的表上做一个SELECT:

  • ID
  • 用户名
  • 速度
  • is_running

声明如下:

SELECT * 
  FROM mytable 
 WHERE username = 'foo' 
   AND is_running = 1

我有“用户名”的索引。如果我正在运行上述语句,是否还需要索引“is_running”以获得最佳性能?或者只是选择的第一列有所作为?我正在使用mysql 5.0。

3 个答案:

答案 0 :(得分:1)

这取决于您要存储的数据类型。如果它是bool,你可能无法单独从该列的索引中看到收益。您可能希望尝试在两列上添加复合索引:

ALTER TABLE mytable ADD INDEX `IDX_USERNAME_IS_RUNNING` ( `username` , `is_running` );

答案 1 :(得分:0)

如果您需要索引,最终将取决于表中的数据量。在许多情况下,如果引擎认为更快,引擎可能只进行表扫描并省略您的索引。你有100个用户,或100,000个用户吗?

在bit / bool列上你不会为索引使用大量的存储空间,所以除非你的插入率非常高,否则它可能不会受到伤害。

答案 2 :(得分:0)

如果你有一个拥有100万用户的表,并且任何时候只有1或2个正在运行 - 当然,通过is_running进行索引,它将为你提供出色的性能。这个特定的用例最好在列上有2个索引 - 用户名,isrunning。 2个索引的原因是您要求is_running=0,在这种情况下它会使用username索引。

否则,复合索引有0%的可能性(用户名,isrunning)帮助任何事情。坚持用户名上的单个索引。

最后,你真的需要整个记录吗?选择 *?在接近tipping point的某些情况下(当MySQL 认为索引+查找变得效率低于直接扫描时),您可以使此查询比原始查询运行得更快。有一个索引(用户名,ID)

SELECT mytable.*
FROM (
SELECT id 
  FROM mytable 
 WHERE username = 'foo' 
   AND is_running = 1
) X
INNER JOIN mytable on mytable.id = X.id