添加索引之后的查询性能下降(Degraded performance of a query afte

2019-08-18 07:09发布

我有一个查询这是相当定期执行SP的哪个部分,并且查询了一段时间来执行,所以我决定去看看它。 我做了查询的自动跟踪,而这是执行计划返回[粘贴在引擎收录由于过度的大小]

我加在其上进行全表访问表的索引,并运行查询。 ,查询性能是差那么之前尽管成本是显著降低 。

为什么会这样,任何人都可以摆脱在同一光?

该数据库是Oracle 10gR2中(版本10.2.0.1.0)。

这是查询正在运行

SELECT DISTINCT CAC_FLEX_03, CAC_FLEX_04
        FROM PCOM_CUST_PRACTICE_INFO A,
             PGIM_ZIP_CODES          C,
             PGIM_PROD_TARIFF_DATA   B,
             PCOM_CODES_APPL_CODES   D
       WHERE A.PCPI_CUST_CODE IN ('002023', '002025')
         AND C.ZC_ZIP_CODE = A.PCPI_PIN_CODE
         AND C.ZC_CITY_CODE = A.PCPI_CITY
         AND C.ZC_COUNTY_CODE = A.PCPI_COUNTY
         AND C.ZC_STATE_CODE = A.PCPI_STATE
         AND B.PTD_CVR_CODE = 'TF-001'
         AND B.PTD_VALUE_SET2 = A.PCPI_STATE
         AND B.PTD_VALUE_SET4 = A.PCPI_COUNTY
         AND B.PTD_VALUE_SET5 = D.CAC_FLEX_03
         AND D.CAC_FLEX_04 IS NOT NULL
         AND ZC_STATE_CODE =
             (SELECT POL_FLEX_04
                FROM PGIT_POLICY
               WHERE POL_SYS_ID = 541332)
         AND B.PTD_VALUE_SET3 =
             (SELECT POL_FLEX_01
                FROM PGIT_POLICY
               WHERE POL_SYS_ID = 541332)
         AND CAC_TYPE = 'TERR-CODE'
         AND CAC_FLEX_03 = 0;

Answer 1:

一些东西:

首先,如果你正在访问过的数据块的一半,全面扫描速度会更快,因为读取索引块是另一个IO调用,因此索引行的读取通常是贵一倍的时间明智的阅读顺序行。

其次,你需要看看你的计划有和没有索引。 这里会有的信息,可以让你知道什么改变。 如果你看到一个“合并联接笛卡尔”企划犯了一个错误。 该计划是本性难​​移。 全扫描内环具有相同的IO成本,但需要较少的内存和临时空间。

第三,建有ANALYZE TABLE统计。 别。 即使甲骨文说,这是坏的,坏了。 使用dbms_stats包来构建你的属性,你会得到更准确的统计数据。 如果它仍然是奇数,改变你的样本大小,或做全统计资料,而不是估计。



Answer 2:

我见过查询得到这样当索引表小慢。 查询计划从构建一个临时哈希表来使用(基于树的)指数,这是比较慢(但会更好比例)改变。 基于成本的优化器并不总是正确的可用的统计信息得到它,实际上它不能,如果你想它。 对于较复杂的查询计划,它不会是能够准确地预测性能,而这样做的查询。



Answer 3:

只是为了兴趣,是表PGIM_ZIP_CODES真的是在查询所需? 它看起来对我来说,改变“AND ZC_STATE_CODE =” [的SQL线16]为“和A.PCPI_STATE =”允许你从查询的清除体内PGIM_ZIP_CODES。

其次,它看起来像PGIM_PROD_TARIFF_DATA创建的索引没有做好这方面的工作 - 在我有限的经验,只有78K行的表通常更快表扫描,除非添加索引是唯一的或者降低了对于该表中的计划的首页 - 只有查询(第二个计划看起来像2项指标均在桌子上创建的,他们不是唯一的)。

第三,现在我已经看了有点困难。 它看起来像你的查询可以解析为:

选择不同CAC_FLEX_03,CAC_FLEX_04

从PCOM_CODES_APPL_CODES

其中CAC_FLEX_03 = 0

和CAC_TYPE = 'TERR-CODE'

其中存在(等等等等等等)

  • 总是假设所要求的其中存在 - 因为来自表A中的结果行的存在,B和C将确实从与CAC_FLEX_03 = 0和TYPE表d返回的所有行的=“TERR-CODE”

PS我有我没有误解的问题!



Answer 4:

我们也有类似的问题,它原来是索引碎片。 让你的DBA检查你正在使用,看看是否需要重建任何需要索引的所有统计数据。

记住,在线重建将让你走一段时间,但脱机重建可能需要在某些时候做。



Answer 5:

没有查询“ 应该 ”永远的不利通过添加新的指数的影响。 只有写操作(即需要修改的指标)不应当由索引的存在减慢),即使是有碎片应该比没有索引速度在所有的索引。 如果你刚刚添加的指标,它的品牌东西方妇女网络(或多或少),不应该被分割到任何明显的程度。 添加到这一点,你说成本数字是低,我怀疑你有别的东西怎么回事无关的指标。 有没有可能是其他一些交易可能会暂时放在一些查询所需数据行的读锁和阻止它的一些相当长的时间?



Answer 6:

什么查尔斯Brentana写明的相似,添加索引不应降低查询的执行。

如果所有的统计信息是最新的,这样的基于成本的优化器选择一个好的执行计划,这将是真实的。 再次,请仔细检查统计,无论是在表和索引。

如果一切犹太那里,我只能假设存在影响查询的性能的一些其他因素。 还有没有其他负载DB服务器上(长时间运行的批处理作业,备份等),以便查询运行更久? 是否有您所使用的查询表中的一个重大的更新活动? 已经在数据库高速缓存中的数据第一次,但不是第二次? 我不知道如何测试这两种说法并排的一面,但我们有了一些原因,这种奇怪的行为...



Answer 7:

你需要知道的是,基于成本的优化,同时是相当复杂,大部分的时间是正确的,可能是错误的时候。

有大量的Oracle提供特定的文献(例如见汤姆凯特的博客),清楚地证明,添加索引其实是可以降低SELECT语句的性能。 在其他的原因,通过索引访问数据集可以比完全扫描做,如果数据的密度足够高更昂贵。

有时候,你可以使基于成本的优化器通过为所涉及的列直方图知道数据的分布,但即使这样有时会失败。 我想尝试第一次产生直方图的索引列,如果失败的话,我们将不得不在你的发言,并访问计划再看看。



文章来源: Degraded performance of a query after adding Index