代码之家  ›  专栏  ›  技术社区  ›  Ronbear

更改视图定义可以改进/降低两种不同的查询

  •  0
  • Ronbear  · 技术社区  · 6 年前

    因此,我们有许多Oracle视图,我们将这些视图公开给其他团队使用,他们对这些视图运行查询以提取数据。

    最近,我们意识到,在我们公开的视图中,有一个用户对日期范围进行了select*操作,但查询并没有及时返回。经过调查,我们决定通过将选择子查询转换为左连接来“优化”视图,我知道这通常会提高查询性能。

    上一个视图定义:

    select a.date, (select name from table_b b where b.id = a.id), a.id
    from table_a a
    

    新建视图定义:

    select a.date, b.name, a.id
    from table_a a left join table_b b on a.id = b.id
    

    我们用用户对其进行了测试,现在他的查询性能大大提高了,因此更改已推广到生产中。一天后,我们意识到另一个用户在某个复杂的查询中使用了此视图,他的查询从每天运行2小时变为>7小时或根本没有完成。

    所以我想我的问题是,如何处理这个调优问题,即提高一个查询的性能会降低另一个查询的性能?我正在进行回滚,以便检查两个不同的查询计划,但我不确定我可以从计划差异中获得什么见解。我查看了表格统计数据,它们看起来都不错。

    1 回复  |  直到 6 年前
        1
  •  1
  •   APC    6 年前

    “用户对日期范围进行了选择*”。

    众所周知,日期范围扫描很难调整。一个非常适合 date '2018-04-01' to date '2018-04-02' 可能会很糟糕 date '2017-04-01' to date '2018-04-01' 。当然,反之亦然。

    因此,您可能在这里遇到的问题是,您的用户正在使用绑定变量作为日期范围值。绑定变量通常有助于提高性能,因为它们允许Oracle对查询的所有执行重复使用相同的执行计划,并为这些变量指定任何值。当相关值具有正态分布时,这是一件好事。然后,我们节省了硬解析的成本,并使用了有效的路径。这称为绑定变量窥视。

    然而,当数据分布不均或指定范围时,我们需要不同的策略。与使用索引读取来检索表中20%的行相比,硬解析的开销微不足道。因此,您需要一种不同的方法,一种不依赖于绑定变量的方法。理想情况下,您可以与用户一起工作,了解他们在做什么,并帮助他们编写更好的查询。但是,Oracle数据库确实具有自适应游标之类的功能,允许数据库评估缓存的计划是否仍然适合绑定变量的新值。这并不能保证良好的性能,但在用户运行特殊查询的情况下会有所帮助。 Find out more


    “基础表是按日期分区的,也按日期索引的,因此我认为日期范围不应成为问题。”

    信念与证明不同。如果日期范围在单个分区内,那么可能不是问题所在。如果查询的范围跨越多个分区,那么它就是潜在的罪魁祸首。考虑:如果您的表被划分为“一天”部分,则日期范围为 日期“2017-04-01”至日期“2018-04-01” 将扫描 365个分区 。分区修剪对您没有多大帮助。但如果你认为这不值得调查,那很酷。

    “我的一般问题是如何调整一件事而不破坏另一件事(你可能没有意识到)”

    我想你已经知道了,这是不可能的。我们所能希望的最好方法是调整查询,使其在我们所知道的条件下以最佳方式执行。如果可以编写一个查询,使其在任何场景中都能完美执行,那么所有Oracle调优顾问都不会像他们那样生活得很好。