2011-06-07 82 views
0

有沒有優化下面的查詢的方法?它返回正確的記錄,但需要一分多鐘才能執行。在Oracle中用NULLable列優化查詢

select STATUS, SUBNO, TRUNC(TRSF_DATE) TRSF_DATE 
from 
(
    select STATUS, SUBNO, TRUNC(TRSF_DATE) TRSF_DATE 
    from tbl  where 
     trsf_date is not null and 
     contrno in ('8', '8A', '8B', '8C', '8D', '8E', '8PH3A', '8PH3B', '8PH3C', '8PHD') 
) 
where trsf_date = to_date('5/21/2011', 'mm/dd/yyyy')** 

的要求是,返回記錄,其中:

  1. contrno在( '8', '8A', '8B', '8C', '8D', '8E','8PH3A 」, '8PH3B', '8PH3C', '8PHD')
  2. trsf_date =一些具體日期

注意的trsf_date列可以爲空,我不得不使用trsf_date在WHERE子句中。這就是爲什麼我使用內部查詢首先獲取NOT NULL行,然後從中選擇行。否則查詢將會卡住而不返回任何行。

+0

你正在使用哪個數據庫? – Akhil 2011-06-07 07:03:25

+0

看起來像甲骨文。 – ErikE 2011-06-07 08:31:34

+1

我看不到明顯的錯誤(我確定查詢優化器會合並條件)。向我們顯示執行計劃 – 2011-06-07 08:47:22

回答

2

的DBMS處理空值當遵守ANSI時爲unknown。這意味着像Column = /value/這樣的表達式將自動排除NULL,而不再有其他條件。所以下面簡單的查詢應該做的工作:

SELECT 
    STATUS, 
    SUBNO, 
    TRUNC(TRSF_DATE) TRSF_DATE 
FROM crm_user_info 
WHERE 
    TRSF_DATE = To_Date('5/21/2011', 'mm/dd/yyyy') 
    AND CONTRNO IN ('8', '8A', '8B', '8C', '8D', '8E', '8PH3A', '8PH3B', '8PH3C', '8PHD') 

加快這你可以把指標在TRSF_DATECONTRNO列。

-1

您不需要內部查詢。您可以在WHERE條件合併成1個查詢:

select STATUS, SUBNO, TRUNC(TRSF_DATE) TRSF_DATE 
    from crm_user_info 
    where 
     trsf_date is not null and 
     trsf_date = to_date('5/21/2011', 'mm/dd/yyyy') and 
     contrno in ('8', '8A', '8B', '8C', '8D', '8E', '8PH3A', '8PH3B', '8PH3C', '8PHD') 

此外,爲加快查詢,您可以使用查詢提示,如WITH(NOLOCK)在SQL Server:

select STATUS, SUBNO, TRUNC(TRSF_DATE) TRSF_DATE 
     from crm_user_info WITH(NOLOCK) 
+0

推薦NOLOCK不好。 – ErikE 2011-06-07 08:34:52

+0

實際上取決於需要。如果應用程序與糟糕的閱讀OKAY,這就是所有你暗示SQL Server。 – Akhil 2011-06-07 16:26:21

+1

將NOLOCK推薦爲一般性能工具是不負責任的。請參閱[this](http://www.sqlservercentral.com/articles/performance+tuning/2764/)和[這表明您可以獲得重複的行](http://sqlblogcasts.com/blogs/tonyrogerson/archive /2006/11/16/1345.aspx)。它只適用於狹窄的環境,需要專家的知識才能確保正確使用它。另外,你不需要'trsf_date不爲空',因爲它將被等號運算符排除。 – ErikE 2011-06-07 16:39:42

-1
select STATUS, SUBNO, TRSF_DATE 
from crm_user_info 
where isnull(trsf_date,'01/Jan/1753') = '07/Jun/2011' 
and contrno in ('8', '8A', '8B', '8C', '8D', '8E', '8PH3A', '8PH3B', '8PH3C', '8PHD') 
+0

在Oracle中,不是'isnull',而是寫'NVL(trsf_date,...)' – 2011-06-07 08:43:30