我使用SQL查询是类似于以下形式:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
AND table1.period = table2.period

和它要么太慢或者有什么地方锁死,因为它需要至少4分钟返回。如果我将其改为这样:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
WHERE table1.period = table2.period

然后正常工作(虽然没有返回列的权数)。有什么办法来加快这?

<强>更新:它做同样的事情,如果我切换后者查询的最后两行:

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.period = table2.period
WHERE table1.person_uid = table2.person_uid

<强>更新2:这些是实际观看我正在接合。不幸的是,他们是一个数据库,我没有控制权,所以我不能(容易)做出索引的任何变化。我倾向于认为这是一个索引问题虽然。虽然接受情况的解答之前有调整一些神奇的方式此查询,我不知道我会等待一点点。否则,我会接受目前的答案之一,并试图找出另一种方式做我想做的事情。感谢大家的帮助迄今为止。

有帮助吗?

解决方案

记住,语句2和3是与第一个不同。

如何?嗯,你正在做一个左外连接,你的WHERE子句不考虑到这一点(如ON子句一样)。至少,尝试:

SELECT col1, col2
FROM table1, table2
WHERE table1.person_uid = table2.person_uid (+)
AND table1.period = table2.period (+)

,看看你是否得到相同的性能问题。

你有什么索引这些表?由外键约束定义这种关系?

什么你可能需要的是在两个person_uid和周期(在两个台)的复合索引。

其他提示

我想你需要理解为什么最后两个是不一样的查询作为第一个。如果你做了左连接,然后添加一个where子句对连接的右侧的表referncing一个字段(其中一个可能并不总是有一个记录相匹配的第一个表),那么你就有效地改变了加盟内连接。有一个例外,那就是如果你引用像

SELECT col1, col2
FROM table1
LEFT OUTER JOIN table2
ON table1.person_uid = table2.person_uid
WHERE table2.person_uid is null

在这种情况下,你要求不具有在第二表中的记录备案。但是,除了这种特殊情况外,要更改左连接为内部连接,如果你在表2 refence场在where子句中。

如果您的查询速度不够快,我想看看你的索引。

任何有人告诉你根据你所提供的信息是一个猜测。

看为查询执行计划。如果您没有看到一个原因,该计划进展缓慢,在这里发布计划。

http://download.oracle的.com /文档/ CD / B28359_01 / server.111 / b28274 / ex_plan.htm#PFGRF009

你有覆盖在person_uidperiod索引两个表?

如果没有,添加它们,然后重试。

看看执行计划,看看该查询实际上做。

另外:有哪些字段的数据类型?他们是两个表中的一样吗?隐式转换才能真正放慢改革的步伐。

做这些表是否与你所参加的列的索引?安装Oracle的免费的SQLDeveloper产品,并利用它做对查询的“解释”,看看它是否在做两个表的顺序扫描。

在左连接你会扫描表1为(person_uid,周期)的每个唯一组合,那么对于所有对应的记录有搜索表2。如果表2没有一个适当的索引,这可以涉及扫描整个该表的太

我最好的猜测,没有看到一个执行计划,是第一个查询(其似乎是正确的唯一一个)的具有表扫描表2以及表1。

正如你说,你不能改变的指标,您需要更改查询。据我所知,只有一个现实的选择...

SELECT
   col1, col2
FROM
   table2
FULL OUTER JOIN
   table1
      ON table1.person_uid = table2.person_uid
      AND table1.period = table2.period
WHERE
   table1.person_uid IS NOT NULL

这里的希望是,你扫描(person_uid,周期)的每个唯一组合表2,但要在表1索引的使用。 (相对于表1扫描和利用对表2的指标,这是我从您的查询预期。)

如果table1中没有相应的指标,但是,你会很不大可能看到任何性能的改善在所有...

民主党。

在更新之一的OP说他实际上是查询视图中不表。在这种情况下,性能完全可以通过直接查询,他特别需要,如果意见是复杂的,加盟不包含的信息,他需要或者他们调用的观点看法许多其他表的表增加。

ANSI加入语法提供JOIN条件和过滤谓词之间的非常明显的区别;这是当写作外连接非常重要。使用EMP /部门表,看看结果从以下两个外连接

Q1

SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on  d.deptno = e.deptno
and loc in ('NEW YORK','BOSTON' )
;

DNAME              DEPTNO ENAME             MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING             10 CLARK            7839 NEW YORK
ACCOUNTING             10 KING                  NEW YORK
ACCOUNTING             10 MILLER           7782 NEW YORK
RESEARCH               20                       DALLAS
SALES                  30                       CHICAGO
OPERATIONS             40                       BOSTON

====

Q2
SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
LEFT OUTER JOIN emp e
on  d.deptno = e.deptno
where loc in ('NEW YORK','BOSTON' )
;

DNAME              DEPTNO ENAME             MGR LOC
-------------- ---------- ---------- ---------- -------------
ACCOUNTING             10 CLARK            7839 NEW YORK
ACCOUNTING             10 KING                  NEW YORK
ACCOUNTING             10 MILLER           7782 NEW YORK
OPERATIONS             40                       BOSTON

在第一例子中,示出了Q1是“加入一个恒定”的一个例子。本质上,过滤条件,在进行所述外连接应用。所以,你消除行,随后将其加回外的部分加入。这不一定是错的,但是,这是你真的问的查询?通常它是在Q2中所示的结果是必需的是,这里的过滤器之后应用(外)加入。

还有一个性能含义也为大的数据集。在许多情况下,加入上的恒定,必须通过创建一个侧视图,它通常只能通过一个嵌套循环来优化由优化内部解决加入,而不是一个散列连接

对于开发商谁是熟悉Oracle外部联接语法,查询可能会被写成

SELECT dname, d.deptno, e.ename, e.mgr, d.loc
FROM dept d
        ,emp e
where  d.deptno = e.deptno(+)
and loc in ('NEW YORK','BOSTON' )

此查询在语义上等同Q2的上方。

因此,在总结,那就是你理解了JOIN子句和写作时ANSI外部连接的WHERE子句之间的不同非常重要的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top