【问题标题】:Performance issue with my query.Please suggest我的查询存在性能问题。请提出建议
【发布时间】:2011-11-26 18:45:28
【问题描述】:
MERGE INTO Analysis a
USING ( SELECT * FROM  Data ) b
ON ( a.User_Id = b.User_Id AND a.Upgrade_Flag = 0 )
WHEN MATCHED THEN
UPDATE SET Status = NVL(a.Status, 'ACTIVATE');

上述查询工作正常。但是当存在数百万条记录时,这可能会导致性能问题。上述查询是否有任何替代方法以获得更好的性能。请就此提出建议。感谢您的宝贵时间

【问题讨论】:

  • 您能告诉我们该语句的执行计划吗?
  • 性能调优是一个证据收集问题。因此,您需要提供更多信息。两个表的数据量,数据的分布,哪些列被索引。还要解释查询计划和统计信息。还有指示性时间,包括您认为应该是合理的时间。最后,上下文:这是一份常规工作还是一次性工作?

标签: oracle oracle10g query-optimization oracle11g


【解决方案1】:

没有看到执行计划,我无法预测替代方案是否会更有效。但我注意到您没有在更新中使用合并源,这表明这可以重写为简单的更新语句:

UPDATE Analysis a
SET Status = NVL(a.Status, 'ACTIVATE')
WHERE a.Upgrade_Flag = 0
AND a.User_Id IN (
  SELECT b.User_Id FROM Data b
)

与这些事情的情况一样,您可以选择使用IN 子句,如我所展示的,或者使用带有相关子查询的EXISTS 子句。通常在尝试调整性能时测试这两个选项是值得的,尽管至少在某些情况下优化器会自行尝试这种转换。

【讨论】:

    【解决方案2】:

    查询对我来说看起来不错。也许你应该创建一些索引?

    如果尚未创建,则为 Analysis.User_Id 和 Data.User_Id 创建索引(主键自动创建索引)。

    或者也可以为包含 User_Id 和 Upgrade_Flag 列的 Analysis 创建索引。

    【讨论】:

    • Juho:@peter 索引已经创建。但是,由于有数万亿条记录,它是否会随时导致性能问题?
    【解决方案3】:

    您使用 MERGE 而不是简单的 UPDATE 的原因真的一点也不明显。

    update analysis a
    set a.status = 'ACTIVATE'
    where a.status is null
    and a.upgrade_flag = 0 
    and a.user_id in ( select b.user_id from  data b )
    /
    

    假设 DATA.USER_ID 已编入索引,仅从 DATA 中选择 USER_ID 而不是整个记录可以加快处理速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 1970-01-01
      相关资源
      最近更新 更多