小编典典

低选择性色谱柱的索引和替代方法

sql

在低选择性色谱柱上选择记录的策略范围是什么?

一个示例可能是订单表,多年来,您在其中构建了大量已完成的订单,但经常需要选择活动订单。订单可能会经历生命周期,例如下达,分配库存,从仓库提货,发货给客户,开票并付款。订单可能会另外被取消,保留等。大多数记录最终将处于最终状态(例如已付款),但是您可能经常需要选择已分配的订单。在这种情况下,顺序读取将很慢。

关于对
MySQL进行索引的类似问题:低基数/选择性列=如何进行索引?
索引会吸收SQL吗?
什么是索引,如何使用它们来优化数据库中的查询?
定义索引:哪些列对性能有影响?和许多其他的相关性逐渐降低。

我已经读过的方法(在其他地方)包括

  • 使用位图索引
  • 使用部分索引(create index x on t(c2) where c1='a'
  • 使用聚集索引?
  • 不要索引低选择性的列,请使用顺序读取
  • 将数据分区(例如,分成几个具有相同架构的表)
  • 使用补充表(例如 active_customers(customer_id)

我当前的DBMS不支持上面列出的前三个选项,其余的似乎有问题-还有其他常用的方法吗?

更新:我见过-为您的低选择性色谱柱建立索引,但只有为高选择性值进行选择。


阅读 174

收藏
2021-03-23

共1个答案

小编典典

我同意非理性的 不过 分支。但是,这种情况下有些事情要知道。

这称为歪斜和歪斜杀死。这对于部分索引是一种完美的用法,在该索引中,您将排除95%的已付款发票,而仅对更有趣和更具选择性的统计信息进行索引。但是你没有。您可以将所有行水平划分到单独的表/分区中,但随后需要考虑行迁移(从一种状态迁移到另一种状态),这很昂贵。DBMS必须执行更新,删除和插入才能更改状态。如果您使用的是大容量系统,那将会很痛苦。

忘记您关于是否基于选择性建立索引的说法,因为将索引放在快速变化的列上通常也是一个坏主意。您的索引将包含热块,其中所有步骤1都将被删除,另一个将所有步骤2都将被插入,并且顺便说一句,某些步骤2同时被删除到了步骤3中。这将无法很好地扩展。

我建议将您的状态垂直划分到一个单独的表中。

您的发票表将包含一个PK和除状态之外的所有列。

您可以通过两种方式处理您的身份。该表将具有PK值作为返回发票表的FK,状态以及您输入该状态时的时间戳。最好的是关于状态的水平分区表。您将为每个可能的状态分配一个分区。因此,找到全部或一个“已放置”状态将对修剪进行分区,并仅读取所需的分区-
这是很少的块。由于该行非常狭窄,因此您可能在单个块上获得400个发票状态。查找任何一张发票的状态都很容易,因为PK上有一个全局索引。

如果RDBMS不支持通过行迁移进行分区,则需要将这些分区作为表进行管理,然后从一个表中删除并插入另一个表中。您将把这些移动封装在一个过程的事务中,以便保持数据干净。每张发票都在一个且只有一个状态表中。较难的部分是按发票ID查询,您必须检查每个表以查看其位置。

您还有另一种选择。
您可以写或不写付费状态。如果它是分区表,则只需将其移至已付款状态,就可以从发票状态表中删除该发票。(当然,您会在奖金材料中提到的历史记录表中写一个付费记录)。然后,您将对状态表进行外部连接,并且null表示已支付。如果您几乎从未查询过付费状态,那么实际上没有理由进行快速查询。

奖金材料

无论哪种情况,您都希望在报告表中跟踪这些运动。每次更新状态时,您都希望将其写入历史记录表。最终,您将需要分析我所说的运输时间。从满额到有薪的平均时间是多少个月?由于经济不景气,这种情况会增加吗?从放置到填充的运输时间(以月为单位)是多少?夏季是否因为假期遗失身体而花费更长的时间?你明白了。通过更新该列,您将丢失这些答案,因此您需要将该历史记录日志嵌入到您的过程中。

2021-03-23