【发布时间】:2011-05-10 06:43:56
【问题描述】:
有哪些策略可用于在低选择性列上选择记录?
一个示例可能是一个订单表,在该表中,您多年来积累了大量已完成的订单,但通常需要选择有效订单。订单可能会经历一个生命周期,例如下达、分配库存、从仓库挑选、发送给客户、开具发票和付款。订单可能还会被取消、保留等。大多数记录最终将处于最终状态(例如已付款),但您可能经常需要选择,例如,分配的订单。在这种情况下,顺序读取会很慢。
关于索引的类似问题
MySQL: low cardinality/selectivity columns = how to index?
Do indexes suck in SQL?
What are indexes and how can I use them to optimize queries in my database?
Defining indexes: Which Columns, and Performance Impact?
和许多其他的相关性越来越低。
我读过的方法(在 stackoverflow 和其他地方)包括
- 使用位图索引
- 使用部分索引 (
create index x on t(c2) where c1='a') - 使用聚集索引?
- 不要索引低选择性列,使用顺序读取
- 对数据进行分区(例如,分成多个具有相同架构的表)
- 使用补充表(例如
active_customers(customer_id)
我当前的 DBMS 不支持上面列出的前三个选项,其余选项似乎有问题 - 还有其他常用的方法吗?
更新:我见过 - 索引您的低选择性列,但只选择高选择性值。
【问题讨论】:
-
我通常建议此时进行分区。为什么这看起来有问题?
-
我想我正在考虑为每个状态值分区到一个单独的表中,因此最终需要维护大量表以及将记录从表移动到表的复杂代码。但是我想您可以将数据划分为 status=final 和“其余”。即便如此,有时您可能想要选择所有记录而不考虑状态(例如某种月度销售报告),但我没想到需要做多少额外的工作。
-
@littlegreen。我并不是真的在寻找特定于 DBMS 的建议或升级指导。我想到的 DBMS 是 Informix SE,但请不要专注于此。
-
@RedGrittyBrick,至于分区,一些数据库引擎可以自动按列值分区(并且有两个级别 - 从逻辑上讲它可能仍然是单个表,例如只是物理存储在不同的 HDD 上)。如果您实际上创建单独的表,将它们连接回来需要维护一个 UNION ALL 视图(就是这样)。
-
您是否真的遇到了性能打击,或者这是一个智力锻炼?只是好奇。
标签: sql database-design indexing relational-database