我有几张桌子,我想知道我的综合索引是否有用。我正在使用MySQL 5+
,但我想这适用于任何数据库(或不是?)。
无论如何,请说下表:
username active
-----------------------------------
Moe.Howard 1
Larry.Fine 0
Shemp.Howard 1
所以我通常会选择:
select * from users where username = 'shemp.howard' and active = 1;
active=1
用于我们的许多表格中。通常,我的索引会在username
列上,但我想添加活动标志(到同一索引)。
我的逻辑是,当查询引擎正在扫描索引时,它会扫描索引,如:
moe.howard,1
shemp.howard,1
larry.fine,0
并在遇到非活动用户(Larry)之前找到Shemp
。
现在,我们的active
列通常是TINYINTS
和Unsigned
。但我担心索引可能会落后!
larry.fine,0
moe.howard,1
shemp.howard,1
我应该如何最好地处理这个并确保我的索引是正确的?我不应该将活动列添加到与用户名相同的索引中吗?或者我应该为活动创建一个单独的索引并使其降序吗?
感谢。
答案 0 :(得分:2)
如果将复合索引中的这两个字段与active
标志组合作为键的第二部分,则索引顺序将仅依赖于该值(iff)两个或更多的名称字段行是相同的(在这种情况下似乎不太可能,因为假设人们希望系统中的用户名是唯一的)。复合索引中的第一个键将定义键的顺序,只要它们不同即可。换句话说,如果用户名是唯一的,那么将活动标志添加为复合索引的第二段将不会更改索引的顺序。
另请注意,对于示例查询,数据库不会“扫描”索引以查找值。相反,它将寻找第一个匹配条目,在给出的示例中,该条目包含单个匹配。如果多个条目通过WHERE子句,则会发生“扫描”。
话虽如此,除非有很多情况下你有重复的名字,我最初的反应是不创建复合键。如果这些名称“通常”是唯一的,那么你就不会用复合键购买大量的钱。另一方面,如果通常有相当多的重复名称具有不同的active
标志值,则可能有所帮助。那时,您可能需要进行测试。
答案 1 :(得分:2)
实际上我们只能猜测查询优化器会尝试做什么,但通常建议如果索引的选择性超过20%,那么全表扫描优于索引访问。这意味着很有可能即使你索引活动索引也不会被实际使用,因为你有比非活跃用户更多的活跃用户。
MySQL只能按顺序使用索引,因此如果您创建的username,active
复合索引完全没有意义,因为您不会让多个用户拥有相同的用户名。
您确实需要分析您的查询要求,然后您可以设计索引计划来对它们进行处理。描述每个查询,不要试图过度优化所有内容,因为这可能会产生负面结果。
答案 2 :(得分:1)
只有在您希望它可以帮助您过滤/退出的值具有代表性时,才应添加索引。从统计学角度来说。
这是什么意思?
如果说,您正在索引的列上的WHERE子句中的过滤器正在帮助您检索20%的行,您应该在其中添加索引。这个百分比数量取决于你的特殊情况,应该尝试一下,但这就是想法。
在您的情况下,仅通过名称,您将获得100%的排除。在活动列上添加索引将是无用的,因为它无助于减少最终记录集(除非您可能有n次同名但只有一个活动?)
如果您决定仅过滤活跃用户,而不关心名称,情况会有所不同。