gpt4 book ai didi

database - 什么更好/更快 : joining many tables or select one big table

转载 作者:搜寻专家 更新时间:2023-10-30 19:41:32 26 4
gpt4 key购买 nike

我们使用的是 Oracle 11,我们的应用程序是用 Java 编写的。每天一次,通常是下午,我们的数据库会因为很多大的 sql 查询而卡住。我想以某种方式优化这个查询。此查询由许多不同表的连接组成。我的问题是:是使用left join对性能更好,还是将所有信息放在一个表中并使用一个select更好?假设我要为这张表建立一个好的索引。

有关信息:平均而言,一个查询获取 100 兆字节。此外,此查询有时会相互锁定

更新

正在连接 8 个表的表,它们是具有 3-5 列的普通表,其中一列是一些 ID。 SQL 查询看起来像:

SELECT t1.c1,t2.c5, t6.c2, ... FROM t1
LEFT JOIN t2 ON t1.c1 = t2.c1
LEFT JOIN t3 ON t3.c1 = t2.c2
LEFT JOIN t4 ON t4.c1 = t2.c1
LEFT JOIN t5 ON t5.c5 = t1.c1
LEFT JOIN t6 ON t6.c1 = t2.c1
LEFT JOIN t7 ON t7.c3 = t3.c1
LEFT JOIN t8 ON t8.c1 = t2.c1
WHERE something

我的问题是,创建一个由所有连接表组成的新表并使用如下查询是否更好:

SELECT c1,c5, c2, ... FROM SOME_NEW_TABLE

更新 2

这里是 report ,如果有人能对此进行一般性解释,那就太好了。

最佳答案

这个问题我觉得一般都能回答。在对此类查询进行性能调优时,您需要考虑许多事项:

解析时间

建立语句的执行计划需要多长时间?如果查询第一次运行缓慢而之后一直运行很快,那么解析时间就是一个问题。我假设查询中没有变化的常量。如果没有,请使用绑定(bind)变量或作为最后的手段使用动态绑定(bind)变量,但自动引入绑定(bind)变量可能不是一个好主意,请参阅“alter session set cursor_sharing=similar”。

特别是对于旧版本和许多连接(Oracle 8 在解析具有超过 6 个相似身份连接的语句方面真的很糟糕......)解析时间可能很昂贵。 Oracle 11 通常通过在考虑多个执行计划后停止来缩短解析时间。在 Oracle 11 上,解析时间仍然是一个问题,尤其是联合/联合所有。

此外,在此查询中,您使用 ANSI 样式的连接。请注意,在使用更优雅的 ANSI 样式连接复杂语句时,Oracle 11 存在一些性能缺陷。因此对于自动生成的语句我推荐Oracle风格(c(+)=d),对于需要维护的语句你需要研究它是否真的有问题。

当解析时间成为问题时,我建议使用像/*+ ordered */这样的提示作为起点。这样可以确保您的连接顺序是临时生成的数据量尽可能少,并且存在正确的索引。

执行时间

在执行过程中,Oracle执行执行计划。与其他数据库平台相比,Oracle 确实非常高效。但如果执行计划一团糟,执行就需要时间。在您的问题中,您谈论是否预先加入所有内容。

一般来说,最好总是从完全规范化的模型开始。在完全规范化的模型中,数据仅存储一次。因此,当查询得到有效规划时,处理的数据量最少。这假设 Oracle 服务器有足够的内存来缓存它的全部或大部分,因为连接策略有时需要内存中的大量工作空间以及已经从磁盘获取的数据。

当性能不足时,我会先引入提示,但继续使用规范化模型。始终尽量使中间步骤中符合输出条件的数据量尽可能小。当它真的不起作用时,您可能会选择派生表,但我发现这通常是开发技能薄弱的标志。

在所有这一切中,我假设启动执行计划的表中有一个数据量很大,而另一个表较小,可能小一点或小很多。如果不是,则您正在运行“Wiebertje”查询(我没有其他名称,它是荷兰糖果的形状)。然后请阅读第 9 页及更多 conference presentation 2006

获取时间

在循环结束时,Oracle 在某个时刻开始发回数据。尤其是体积可以高度传输它所需的时间。应用程序获取所有内容但只显示前 50 行的情况并不少见。请引入窗口或“获取显示的水印+常量”以减少获取时间。您可能需要在语句或 session 中引入提示,例如/*+ first_rows */以供交互使用。

关于database - 什么更好/更快 : joining many tables or select one big table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20222853/

26 4 0