2012-12-03 69 views
1

我們有很多使用綁定變量的選擇語句,這些語句可能爲空。 Null表示綁定值不應限制該語句。在SQL語句中連接綁定變量(Oracle 11g)

下面是一個簡單的例子,我們在做什麼:

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 | 
----------------------------------------------------------------------------- 

那麼,你認爲什麼是這種外部的最佳解決方案-joins?

+0

我在查詢中看不到任何連接,更不用說外連接了?所以我不太瞭解這個問題。 – Codo

+0

對不起,我使用「外連接」的意思是,綁定值必須「存在」或「不存在」 –

回答

2

我不認爲這個問題可以一般回答,因爲它取決於具體的表模式和可用的索引。

什麼一般可以說是:

  • 兩個建議WHERE條件無法通過索引查找直接找到相關的行。相反,必須完全掃描表或索引。

  • 將同一查詢的不同變體合併爲一個反模式被認爲是一種反模式,因爲Oracle將不得不對所有變體使用相同的執行計劃,這對所有變體而言都是最不理想的。

因此,這將可能會更好要麼:

  1. 構建查詢動態,即添加WHERE條件只有當參數不爲null。如果WHERE條件存在,那麼您仍然應該使用綁定參數,這對於獲得最佳性能至關重要。

  2. 或者,根據參數是否爲空來實現單獨的查詢。

選項1是首選選項。如果您運行C#,Java或類似語言的查詢,實現起來可能更容易。

選項2是您可能從PL/SQL中使用的選項。但是,如果您有幾個可以爲空的參數,則可能會導致許多不同的查詢。