2

假设您有一个表,其中特定的行子集对于读取来说要热得多。就像有一面旗帜is_alive需要一张people桌子。或者,如果您实施软/逻辑删除并且您的搜索条件始终包括is_deleted = 0.

这些字段是否应该包含在这些表的索引中?如果是这样,他们应该更左还是更右?

假设您有类似...的索引

people [ last_name ]
people [ zip_code ]
people [ gender ]

widgets [ category_id ]
widgets [ seller_id ]

你让他们看起来像

people  [ last_name, is_alive   ]
widgets [ category_id, is_valid ]

或者

people  [ is_alive, last_name   ]
widgets [ is_valid, category_id ]

布尔值本身具有低基数/显着性,除非它们与其他搜索条件配对。

尽管几乎每次都使用这个字段,但将这个字段添加到每个索引中只是感觉很可疑。也许这本身就是一个“问题”?是否应该将行传送到具有相同架构的不同表?基本上在标志上进行分区。

供应商不可知论者。

4

2 回答 2

1

索引帮助查询的关键方法之一是减少全表扫描需要读取的页数。请记住,数据库引擎正在管理页面,而页面又存储记录。想象一下,我们有一张客户表,它有一个关于状态的索引。过滤到单个状态的查询只需读取一小部分数据。当然,这个比例可能是 10%(对于加利福尼亚州),而对于一个小州来说则不到 1%。问题是:读取这些数据需要多少页。

要回答这个问题,我们需要信息:(1)查询的选择性如何?(2) 一页有多少条记录?因此,如果 100 条记录适合一个页面,那么选择 2% 行的查询几乎总是必须读取所有页面。在这种情况下,索引对全表扫描没有帮助。该索引反过来会产生开销,因此可能不应该使用它。

另一方面,如果一个页面上只有一条记录,那么选择 2% 行的查询将只需要读取 2% 的页面 - 节省 50 倍。索引产生的几乎任何开销都是值得的。

因为索引被用于多种用途,并且因为不同的数据库引擎以不同的方式实现它们,并且因为页表的实现方式不同等等,所以没有硬性规定。但是,我通常可以说低基数标志可能不是索引的好选择。

当我想到它时,我可以想到索引可能被证明是有效的一种情况。这将适用于可以由索引专门处理的宽行和查询(select flag,count(*) from table group by flag)。

另一方面,如果您有多个此类标志,则复合索引可能有助于提高查询性能。

于 2012-05-09T18:08:42.113 回答
0

一些 RBDMS 甚至不允许您在位字段上放置索引,例如 SQL Server 2000...

不过,应该与供应商无关的东西……通常是索引的选择性决定了它的有用性。

如果您有一个索引is_alive,并且拆分为 50% 活着/50% 死亡,那么该索引的选择性不够有用。

但是,如果拆分更像是 99% 活着,1% 死了……那么在搜索死人时可以使用索引,但在搜索活人时会忽略该索引。

因此,如果有一小部分行具有该字段的特定值,并且您足够频繁地搜索具有该特定值的行以证明索引维护的开销是合理的,则索引可能很有用。

但请记住,这完全取决于您使用的任何 RDBMS,并且您应该针对该特定 RDBMS 测试任何与性能相关的设计注意事项。

于 2012-05-09T18:08:25.140 回答