在 SQL 语句中外连接绑定变量 (Oracle 11g)
Posted
技术标签:
【中文标题】在 SQL 语句中外连接绑定变量 (Oracle 11g)【英文标题】:Outerjoining a Bind-Variable in SQL-Statement (Oracle 11g) 【发布时间】:2012-12-03 14:32:22 【问题描述】:我们有很多使用可以为 Null 的绑定变量的 Select 语句。 Null 表示 Bind-Value 不应限制语句。
这是一个简单的例子:
CREATE TABLE PERSON AS
SELECT LEVEL AS ID, 'Person_'||LEVEL AS NAME
FROM DUAL
CONNECT BY LEVEL <= 5000;
create index IPERSON1 on PERSON(NAME, ID);
begin
dbms_stats.gather_table_stats(user, 'PERSON');
end;
select * from PERSON
where NAME = nvl(:b1, NAME);
select * from PERSON
where (NAME =:b1 or :b1 is null);
这 2 个语句具有以下执行计划:
select * from PERSON where NAME =nvl(:b1, NAME):
------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | CONCATENATION | | | | | |
|* 2 | FILTER | | | | | |
|* 3 | INDEX FAST FULL SCAN| IPERSON1 | 500 | 7500 | 2 (0)| 00:00:01 |
|* 4 | FILTER | | | | | |
|* 5 | INDEX RANGE SCAN | IPERSON1 | 1 | 15 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------
select * from PERSON where (NAME =:b1 or :b1 is null):
-----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
|* 1 | TABLE ACCESS FULL| PERSON | 26 | 390 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
那么,您认为这种外连接的最佳解决方案是什么?
【问题讨论】:
我在您的查询中看不到任何联接,更不用说外部联接了?所以我不太明白这个问题。 对不起,我使用“外连接”的意思是绑定值必须“存在”或“不存在” 【参考方案1】:我认为这个问题不能被普遍回答,因为它取决于特定的表架构和可用索引。
一般可以说是:
两个提议的 WHERE 条件都无法通过索引查找直接找到相关行。相反,必须完全扫描表或索引。
将同一查询的不同变体合并为一个被认为是一种反模式,因为 Oracle 必须对所有变体使用相同的执行计划,这很可能对所有变体都不是最佳的。
所以可能会更好:
动态构建查询,即仅当参数不为空时才添加 WHERE 条件。如果存在 WHERE 条件,那么您仍应使用绑定参数,这对于优化性能至关重要。
或者,根据参数是否为空来实现单独的查询。
选项 1 是首选选项。如果您针对 C#、Java 或类似语言运行查询,它可能更容易实现。
选项 2 是您可能会在 PL/SQL 中使用的选项。但是,如果您有多个可以为空的参数,则可能会导致许多不同的查询。
【讨论】:
以上是关于在 SQL 语句中外连接绑定变量 (Oracle 11g)的主要内容,如果未能解决你的问题,请参考以下文章