2011-02-17 25 views
0

我必须做一个选择在这样一个表:需要在AND语句中对列进行索引?

  • ID
  • 用户名
  • 速度
  • is_running

的说法是这样的:

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

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

+0

假设`is_running`是布尔索引,索引也不会有所作为,因为没有足够的可能性。 – dnagirl 2011-02-17 21:35:26

+0

什么是用户名索引选择性? (即总共有多少行,以及有多少个唯一的用户名) – 2011-02-17 21:36:59

回答

0

它最终将取决于表中数据量是否需要索引。在很多情况下,引擎可能只是进行表扫描,并且如果认为速度更快,则可以忽略所有索引。你有100个用户,还是100,000个用户?

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

+0

如果MySQL预计会得到超过30%的命中数,那么它将忽略索引,因此如果分配非常偏斜,它很可能会被忽略。 – dnagirl 2011-02-17 21:37:24

1

这取决于您正在存储的数据类型。如果它是布尔型的,那么你可能不会仅仅从该列索引中获得收益。你可能想尝试在两列添加复合索引:

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

如果你有100万个用户,只有1或2台运行在任何一个时间 - 通过is_running,它肯定,指数会给你出色的表现。这个特定的用例最好在列上有两个索引,分别是 - username,isrunning。 2索引的原因是如果您要求is_running=0,在这种情况下它使用username索引。

否则,组合索引(username,isrunning)有0%的机会可以帮助任何事情。坚持使用用户名的单一索引。

最后,你真的需要整个记录吗?选择 *?在接近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