Oracle SQL - 子查询工作正常,但是使用该子查询创建表似乎挂起
Posted
技术标签:
【中文标题】Oracle SQL - 子查询工作正常,但是使用该子查询创建表似乎挂起【英文标题】:Oracle SQL - Subquery Works fine, However Create Table with that subquery appears to hang 【发布时间】:2020-05-18 09:02:12 【问题描述】:我有以下查询结构
CREATE TABLE <Table Name> AS
(
SELECT .... FROM ...
)
当我自己运行 SELECT 语句时,它会在几秒钟内编译并返回结果。但是,当我使用 CREATE Table 语句运行它时,我认为它已经挂起并且永远不会编译。
这是什么原因?可以解决什么问题?
Oracle 数据库 12c【问题讨论】:
【参考方案1】:如果您在某些 GUI 中运行 SELECT
,请注意它们中的大多数(如果不是全部)只返回几百行,而不是整个结果集。例如:如果您的查询确实返回了 2000 万行,GUI 会显示前 50 行(或 500,取决于您使用的工具),这有点令人困惑 - 就像它让您感到困惑一样。
如果您将当前查询用作内联视图,例如
select count(*)
from
(select ... from ...) --> this is your current query
它将“强制”Oracle 获取所有行,因此您会看到它实际需要多长时间。
除此之外,看看SELECT
是否可以优化,例如
WHERE
子句中使用的列是否被索引
收集所有相关表的统计信息(用于FROM
子句)
删除ORDER BY
子句(如果有的话;它与CTAS操作无关)
查看解释计划
性能调优远非我所建议的;这些只是您可能想要查看的一些建议。
【讨论】:
所以内部查询是围绕连接表和主表的所有索引设计的。我刚刚计算了所有行数及其大约 800k 行,并在一分钟内返回了它。我之前看过解释计划,并没有什么真正突出的成本高(但是我在这里的知识不是很好)没有按子句的顺序,所以这不是问题。【参考方案2】:您是否尝试过直接加载插入,首先使用 CTAS 创建表,其中 1= 2,然后执行插入。这至少会告诉我们数据是否有问题(损坏的数据)或者是否是性能问题。
【讨论】:
【参考方案3】:我之前也遇到过同样的问题,因为新数据太大(700 万行),我花了 3 个小时来执行代码。
我最好的建议是创建一个视图,因为它占用的空间更少,而不是一个新表。
【讨论】:
【参考方案4】:所以这个问题的答案。
CREATE TABLE <Table Name> AS
(
SELECT foo
FROM baa
LEFT JOIN
( SELECT foo FROM baa WHERE DATES BETWEEN SYSDATE AND SYSDATE - 100 )
WHERE DATES_1 BETWEEN SYSDATE - 10 AND SYSDATE - 100
)
问题在于 BETWEEN 语句与同一时间段不匹配,并且子查询查看的数据多于主查询(我猜这是导致对表进行全面扫描?)
下面的查询有语句时间段之间的匹配,这在不到 3 分钟的时间内返回了结果。
CREATE TABLE <Table Name> AS
(
SELECT foo FROM baa
LEFT JOIN ( SELECT foo FROM baa WHERE DATES BETWEEN SYSDATE - 10 AND SYSDATE - 100 )
WHERE DATES_1 BETWEEN SYSDATE - 10 AND SYSDATE - 100
)
【讨论】:
以上是关于Oracle SQL - 子查询工作正常,但是使用该子查询创建表似乎挂起的主要内容,如果未能解决你的问题,请参考以下文章