更改视图定义会改进/降低两个不同的查询

Posted

技术标签:

【中文标题】更改视图定义会改进/降低两个不同的查询【英文标题】:Changing a view definition improves/degrades two different queries 【发布时间】:2018-04-02 05:04:12 【问题描述】:

因此,我们有许多 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 小时或根本没有完成。

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

【问题讨论】:

how do I deal with this tuning issue - 首先为有问题的查询生成EXPLAIN PLAN 并将计划粘贴到问题中(请将其粘贴为纯文本,而不是位图! !)。如果您想调整查询,这是一个基本步骤。 【参考方案1】:

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

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

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

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


" 基础表按日期分区并按日期索引,因此我认为日期范围不应该成为问题。"

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

“我的一般问题是如何调整一件事而不破坏另一件事(你可能不知道)”

我想你已经知道了,这是不可能的。我们所能期望的最好的结果是调整查询以在我们知道的条件下以最佳方式执行。如果可以编写一个查询使其在任何情况下都能完美执行,那么所有那些 Oracle 调优顾问都不会像他们那样过上好日子。

【讨论】:

感谢您的回答。也许我遗漏了基础表按日期分区并按日期索引,因此我相信日期范围不应该成为问题。我想我的一般问题是如何在不破坏另一件事的情况下调整一件事(你可能不知道)——猜想 rdbms 的世界从未如此简单。

以上是关于更改视图定义会改进/降低两个不同的查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql视图的作用是啥

弹出框控件在选择不同的表视图行时更改其位置

可可objective-c:更改自定义视图的背景颜色

Android:在方向更改时保留相机预览,而其他视图可以旋转

唯一标识两个不同的视图

缩放图像并在图像视图中设置会降低图像质量并挤压它