在我们的数据仓库中,我们有一个巨大的、最常用和最重要的表之一,用于存储帐户数据(他们的 ID、与运营日相对应的 saldo 等)。每天大约有 9000 万行加载到该表中。表是复合分区的,在 OPER_DAY 列上以月为间隔,在 FILIAL 列上列出子分区。该表有 9 个索引,其中 6 个是 Bitmap。
加载如此大量的数据已经花费了大量时间,大约 2 小时,我们进行批量收集并使用 APPEND_VALUES 提示来利用直接路径插入。我们还为表指定 nologging,但由于启用了强制日志记录,这根本不会产生影响。
当前表有 3 年的数据。阅读部分也成为一个问题,如果 OBIEE 用户查询此表以获取一天的信息(例如一天的 saldo 总和),那么它的工作速度很快,但如果用户想查看一两个月,然后速度就变慢了。
有什么方法可以将一个表拆分为多个表,每个表仅存储一年的数据,并将它们全部包含在带有 union all 的新视图中?联合体的每个选择都会有一个条件,这样如果用户查询2023年的数据,那么只会执行联合体的一个选择,如果他运行2022年和2023年,那么将执行联合体内的两个选择,依此类推?因此,不需要扫描整个表,只会选择拆分后需要的表。
我们使用这种方法面临的主要问题是我们不知道 OBIEE 用户将在分析中设置日历上的哪些过滤器。我们有一个想法使用 SYS_CONTEXT,并为会话设置上下文参数,但我们找不到从 OBIEE 过滤器设置上下文的方法,我们仅通过使用仪表板提示来设置会话变量。有可能吗?或者还有其他方法吗?
有什么办法可以将一个表拆分成多个表,每个表只存储一年的数据
这就是分区的作用(在数据库级别),并且您已经在月份级别使用分区。假设
OPER_DAY
将在用户查询中被过滤,那么您应该已经进行分区消除以减少读取的数据量。
如果您每天加载 9000 万条记录,那么您将拥有大量数据,因此需要一些时间来加载和查询。关于加载数据,您可以做很多事情,但性能调整取决于您的系统和代码,不可能为您提供任何特别有用的信息,只能提供一般建议。
首先我假设您有硬件可以应对这个容量?您是否在 RAC 上并行运行?您没有提及,所以我假设您没有使用 Exadata。
我猜测每天有 9000 万条记录,数据主要(仅?)是新的和插入的而不是更新的?如果是这样,您的第一个瓶颈将是所有数据都是新的,因此所有数据都将访问相同的段。根据
FILIAL
的分布,子分区可能会阻碍您而不是提供帮助。
如果是插入,则仅检查执行计划是否实际上正在执行直接路径插入。您可以将所有提示放入您喜欢的内容中,但如果不可能直接路径,您将无法获得好处。
根据您获得的许可,高级压缩也可能有所帮助。
索引并不总是有帮助。如果它们没有被使用,那么您只是引入了为此而更新索引的瓶颈。
最终你需要看看数据库在哪里,瓶颈在哪里,然后寻找解决方案。
您可以做很多事情,但我怀疑尝试将事情分段只会给您带来其他问题。如果你真的想这样做,那么看看碎片。
我怀疑报告不需要所有数据,它们正在聚合并删除列。提高报告速度的最佳选择是创建聚合并将它们添加为单独的逻辑表源。这对用户来说都是不可见的,但如果他们的查询可以通过现有的聚合来满足,那么现有的聚合将被使用并将大大减少响应时间。
除此之外,您又回到了性能调优,这听起来可能会再次进行数据库调优,并查看物理查询的解释计划并寻找可以改进的地方。
OBIEE 确实有一个碎片选项,允许您在逻辑源中使用多个表,并根据过滤条件,它将使用适当的表。如果您想按年份创建单独的表格,您可以查看该选项。