使用dblink返回结果需要一天时间的Oracle Sql查询
伙计们,我有下面的oracle sql查询,它提供了日期之间的monthwise报告。基本上,对于11月,我需要11月1日到11月30日之间的值的总和。 正在查询的表位于另一个数据库中,并使用dblink进行访问。DT列为数字类型(对于ex 20101201) 以下是我今天要做的事情,任何额外的提示都会很有帮助。使用dblink返回结果需要一天时间的Oracle Sql查询,sql,oracle,query-optimization,Sql,Oracle,Query Optimization,伙计们,我有下面的oracle sql查询,它提供了日期之间的monthwise报告。基本上,对于11月,我需要11月1日到11月30日之间的值的总和。 正在查询的表位于另一个数据库中,并使用dblink进行访问。DT列为数字类型(对于ex 20101201) 以下是我今天要做的事情,任何额外的提示都会很有帮助。 我将收集此表的表态统计数据,这可能会给出最佳结果 执行计划 检查是否为分区创建了本地索引 使用BETWEEN代替>=和可能是因为以下几个问题: 1.网络速度,因为数据库可能位于不同的硬
有一个类似的问题。可能是因为以下几个问题: 1.网络速度,因为数据库可能位于不同的硬件上。 但是,您可以参考此链接 .
还有一个类似的问题。如果不知道表结构、约束、索引、数据量、结果集大小、网络速度、并发级别、执行计划等,就无法回答 我会调查一些事情: 如果表已分区,则查询所命中的分区是否存在统计信息?一个常见的问题是,在插入数据之前,统计数据是在一个空分区上收集的。然后,当您查询它时(在刷新统计数据之前),Oracle会选择索引扫描,而实际上它应该在该分区上使用FTS 也与统计相关:确保
WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD'))
其中DT>=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
和DT
生成与以下内容相同的执行计划:
WHERE DT >= 20101201
AND DT < 20110101
式中DT>=20101201
和DT<20110101
已更新
您使用的是什么版本的Oracle?我提出这个问题的原因是,在Oracle 10g及更高版本上,本例中应该选择另一个group by实现(哈希而不是排序)。看起来您基本上是在对从日期筛选器返回的3.42亿行(14 GB)进行排序。你有备用的公羊吗?否则,您将执行多路径排序,溢出到磁盘。这很可能就是正在发生的事情
根据计划,将返回大约790行。这是对的吗?
如果是这样,您可以排除网络问题:)
另外,我对该计划的格式并不完全熟悉。这张桌子是分区的吗?否则我就无法获得分区#11引用。如果不知道表结构、约束、索引、数据量、结果集大小、网络速度、并发级别、执行计划等,就无法回答 我会调查一些事情: 如果表已分区,则查询所命中的分区是否存在统计信息?一个常见的问题是,在插入数据之前,统计数据是在一个空分区上收集的。然后,当您查询它时(在刷新统计数据之前),Oracle会选择索引扫描,而实际上它应该在该分区上使用FTS 也与统计相关:确保
WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD'))
其中DT>=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
和DT
生成与以下内容相同的执行计划:
WHERE DT >= 20101201
AND DT < 20110101
式中DT>=20101201
和DT<20110101
已更新
您使用的是什么版本的Oracle?我提出这个问题的原因是,在Oracle 10g及更高版本上,本例中应该选择另一个group by实现(哈希而不是排序)。看起来您基本上是在对从日期筛选器返回的3.42亿行(14 GB)进行排序。你有备用的公羊吗?否则,您将执行多路径排序,溢出到磁盘。这很可能就是正在发生的事情
根据计划,将返回大约790行。这是对的吗?
如果是这样,您可以排除网络问题:)
另外,我对该计划的格式并不完全熟悉。这张桌子是分区的吗?否则我就得不到分区#11参考。像往常一样,对于这类问题,解释计划会很有用。这将有助于我们了解数据库中到底发生了什么 理想情况下,您希望确保查询在远程数据库上运行,并返回结果集,而不是通过链接发送数据并在本地运行查询。这可确保通过链路发送的数据更少。
DRIVING\u站点
提示可以帮助实现这一点,尽管Oracle通常对此相当聪明,因此可能根本没有帮助
Oracle似乎在运行远程查询方面做得更好,但仍然可能存在问题
此外,简化一些日期转换可能会有好处
例如,替换此:
TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')- 1,'MM'),'MONYYYY')
WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD'))
为此:
TO_CHAR(add_months(TRUNC(SYSDATE,'MM'), -1),'MONYYYY')
它可能稍微更有效,但也更容易阅读
同样,替换此:
TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')- 1,'MM'),'MONYYYY')
WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD'))
其中DT>=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD'))
和DT
与
式中DT>=TO_编号(TO_字符(添加_月(TRUNC(SYSDATE,'MM'),-1),'YYYYMMDD'))
和DT
甚至
WHERE DT >=TO_NUMBER(TO_CHAR(add_months(SYSDATE,-1),'YYYYMM"01"'))
AND DT < TO_NUMBER(TO_CHAR(SYSDATE,'YYYYMM"01"'))
式中DT>=TO_编号(TO_字符(加上_月(SYSDATE,-1),'YYYYMM“01”))
和DT
像往常一样,对于这类问题,解释计划会很有用。这将有助于我们了解数据库中到底发生了什么
理想情况下,您希望确保查询在远程数据库上运行,并返回结果集,而不是跨数据库发送数据