2014-03-01 51 views
1

where子句中的列不具有选择性。他们都在一张单人桌上。另外,使用的表达式不等于,或,IS NULL,IS NOT NULL。主键在客户ID上。我不确定如何避开这类数据。是否有不同的索引方法可以在表格上创建或以其他方式解决问题。我猜想分区对于将表分成大数据的一个主要部分是没有帮助的。任何想法或解决方法都会有用。正常索引或位图索引无用时如何避免

为了方便理解,我将以下数据作为参考和示例查询。

enter image description here

样本查询
可乐= '适销对路' 或是可乐是空
师范大学指数:由于OR和NULL操作被忽略。此外,查询的数据涵盖了表格中超过95%的数据。 BITMAP索引:由于数据覆盖率超过96%而被忽略。

enter image description here

示例查询
COLB = '7' OR COLB = '6' OR COLB = '5'
NORMAL或BITMAP:两者不有用由于大的数据选择。优化器使用主键cust_id进行全表扫描。

enter image description here

示例查询
COLC <> '特别部分' OR COLC为空(因为这些值可以改变,没有特定的值被传递)

组合示例查询
NOT(COLB = '6'或colB ='3')和 (colC <>'SPECIAL SEGMENT'或colC为空)

回答

3

全表扫描不是邪恶的。索引访问并不总是更高效。

如果您想要返回表中的大部分数据,您希望使用全表扫描,因为这是访问表中大部分数据的最有效方式。当你想访问表中相对较小的数据时,索引非常棒。但是如果你想要大部分数据,那么做数百万次索引访问就不会更有效率。在你的第一个例子中,你想从一个930万行的表中返回920万行。全表扫描是您想要的计划 - 这是检索表格中99%行的最有效方法。其他任何事情效率都会降低。我想,你可能会在A上划分表格,导致两个大分区的完整分区扫描。然而,这只会削减1%的工作量,并且可能会对该表的其他查询产生负面影响。

现在,我总是对想要首先返回表中99%行的查询有点怀疑。例如,在OLTP系统中进行这样的查询是没有意义的,因为没有人会浏览920万行数据。如果目标是复制数据,那么进行这种查询是没有意义的,因为只是每次复制增量更改而不是整个数据集几乎肯定会更有效。如果目标是执行一些聚合,那么读取几乎所有的行可能是有意义的。但如果发生这种事情足以关注优化分析,那么最好查看使用实体化视图和维度预先汇总数据的方法,以便您可以阅读并汇总一次数据,然后再阅读您的运行时预先汇总的值。

如果确实需要读取所有数据,那么您可能还需要考虑并行查询。如果阅读器相对较少,让Oracle并行执行全面扫描更有效,这样您的会话就可以利用更多可用硬件。当然,这意味着您可以减少同时进行的会话,因为对于其他硬件而言,其他硬件意味着更少的硬件,因此这是您需要了解的折衷。如果您正在构建一个ETL过程,其中只有几个会话在任何时候加载数据,那么并行查询可以提供显着的性能改进。

+0

谢谢你的回应贾斯汀。你能指导我如何启用“并行查询”在数据库上运行,或者我可以在其中进一步阅读? – user3090427

相关问题