生产中有一个查询,它运行了几个小时(5-6个小时)。我查看了它的执行计划,发现它忽略了一个大型表上的并行提示。原因-它是通过索引ROWID使用表访问。因此,在我在*+ full(huge_table) */提示之前添加了/ parallel(huge_table)提示之后,查询就开始并行运行,并在不到3分钟的时间内完成。我无法理解的是,为什么表现会有如此巨大的差异。以下是我能想到的并行FTS的优点:
当然,有上述优点,但以下缺点仍然存在:
有了上述知识,我只看到了一个可能导致查询在使用索引ROWID访问时性能较差的原因--某种类似于“繁忙缓冲区等待”的争用。但它并没有出现在AWR前5名的等待事件中。前两个事件是"db文件顺序读取“和"db文件分散读取”。还有什么是我错过的吗?请指点我。
发布于 2014-07-27 17:53:50
首先,在不了解数据容量、统计数据、谓词的选择性等等的情况下,我猜您看到的主要好处是进行表扫描,而不是尝试使用索引。索引不一定快,表扫描也不一定慢。如果您使用索引中的rowid来访问一行,Oracle仅限于执行单个块读取(按Oracle术语顺序读取),并且如果该块有多行感兴趣,它将不得不多次读取相同的块。另一方面,一个完整的表扫描可以完成很好的、高效的多块读取( Oracle术语中的零散读取)。当然,单个块读取将比单个多块读取更有效,但多块读取每字节读取的效率要高得多。此外,如果使用索引,则可能需要定期从索引读取多个块,以找到从表中读取的下一个rowid。
实际上,在表扫描比索引更有效之前,不需要从表中读取那么多数据。取决于许多其他因素,临界点可能在10-20%的范围内(这是一个非常非常粗略的猜测)。想象一下,您必须从电话簿中获得一堆名称,并且电话簿有一个索引,其中包括您正在筛选的信息和条目所在的页面。您可以使用索引查找要查看的单个人的姓名,翻转到指定的页面,记录信息,回翻索引,查找下一个名称,回滚等等。或者只需从名称开始,扫描直到找到感兴趣的名称,记录信息,并继续扫描。不需要太长时间,你就可以忽略索引,只看表中的数据。
添加并行并不会减少查询所做的工作量(实际上,添加并行查询协调意味着您正在做更多的工作)。只是通过使用服务器的更多可用资源,您可以在较短的时间内完成这项工作。如果您使用6个并行从节点运行查询,这肯定会使查询的运行速度提高5倍(由于开销的原因,并行查询的规模明显小于线性)。如果是这样的话,您可能会期望进行表扫描会使查询速度提高20倍,而添加并行性则会增加5的另一个因素,以获得100倍的改进。
https://stackoverflow.com/questions/24983515
复制相似问题