2011-06-07 123 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