2012-05-03 22 views
1

ORACLE数据库中最快的是什么?优化一个SQL查询:调用一个函数或做一个连接?

呼叫select语句中的函数以检索单个值的每一行

SELECT field1, field2, F_GET_LIBELLE_STATUT(field2) FROM table1 WHERE ... 

与简单的功能:

create or replace 
FUNCTION "F_GET_LIBELLE_STATUT" (v_statut NUMBER) RETURN VARCHAR2 IS 
tmpVar VARCHAR2(40); 
BEGIN 
    select libelle into tmpVar from t_statut_ope where id_statut = v_statut; 
    RETURN tmpVar; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     RETURN ''; 
    WHEN OTHERS THEN 
     -- Consider logging the error and then re-raise 
     RAISE; 
END f_get_libelle_statut; 

或做在select语句加入?

Select a.field1, a.field2, b.libelle 
FROM table1 a LEFT JOIN t_statut_ope b ON b.id_statut = a.field2 
WHERE ... 

而且是同样的答案,如果我在选择,并在子句条件调用了大量的功能(十个或更多)?

感谢您的回答。

+2

在这种特定的情况下,普通的加盟将跑赢功能,但这并不意味着它总是会。您应该始终考虑解决方案的执行计划并从中得出结论。 –

+0

@Lieven - 我同意每个案件的优点。但是一个连接总是会比这里发布的查询函数更快。这是公理的。 – APC

+0

@APC - 我倾向于同意,但我对诸如* always *和* never *的绝对声明保持警惕。 –

回答

6

任何可以在SQL中完成的事情都应该在SQL中完成。连接总是比调用该函数更快,因为基于集合的操作总是比排序快的行快。然后你就有了SQL和PL/SQL之间上下文切换的开销。加上处理那些NO_DATA_FOUND异常的开销,这不是真正的例外,因为预期和容忍差距。最后,优化器将为纯SQL选项选择一个更好的计划,因为您已将它提供的所有信息提供给它。

+0

有时选择子查询会更快,然后加入。只需要测试。 –

1

你用这两种不同的查询发现了什么?

根据我的经验,连接速度比功能快10倍。至少当你访问函数中的另一个查询/表/视图时。该函数需要在每次运行时进行评估,联接可能会生成一个更大的数据集,但可以执行得更好,因为它只需要加入表格(在键上),这非常快。

+0

第一个查询(带有函数)在我正在处理的现有应用程序中找到。第二个查询更像我一般的做法,因此在重写所有带连接的查询之前,我试着去了解一个更高效的查询。 – fluminis

2

在函数方法最优的情况下会有很少的情况,并且默认情况下我不会使用它。连接是数据库设计的目标,因此它们应该是您的首选。

0

或忘记了外连接,把SELECT语句确实在选择列表中的翻译[这有时快于外部连接]:

SELECT field1, field2 
, (select libelle from t_statut_ope b where b.id_statut = a.field2) libelle 
FROM table1 a 
WHERE 1=1 
; 
+0

Interresting,你知道什么时候/为什么它快一些? – fluminis

+0

我不认为我见过“选择列表中的select语句”比“outer-join”慢。我怀疑Oracle需要额外的工作来“创建”缺少的记录会导致外连接速度下降。这项工作增加了任何一方的非常大的表格。 –