如何提高where子句或join中列的非确定性函数的性能?

时间:2011-06-03 22:35:52

标签: sql-server performance sql-server-2005 join where-clause

我想提高查询的性能,它有一个带有非确定性函数调用的where子句。

Select Count(*) 
From table1
Where DateDiff(month, Cast(table1.Date As DateTime), GetDate()) = 0

我认为这个问题对于加入同样有效:

Select table1.column1
From table1 Inner Join table2 
On table1.MonthOfHappyness = 
DateDiff(month, Cast(table2.SomeDate As DateTime), GetDate()) 

DateDiff(month, Cast(adrPkt.PktRevDato As DateTime), GetDate()) 

是非确定性的我无法使用计算列创建视图并将其编入索引。 见:SQL Server (2005) - "Deleted On" DATETIME and Indexing

我有哪些选择可以提高效果?

2 个答案:

答案 0 :(得分:3)

除了非确定性函数外,我看到的问题是你在一个字段上进行计算。这(通常)使得该字段上的任何索引都不能被查询使用。

此链接的第二段( Ten Common SQL Programming Mistakes (Functions on indexed columns in predicates) )提供了有关何时发生这种情况的更详细信息,如何避免它以及尽管使用了函数,优化器有时可以使用索引。< / p>

简而言之,通常可以通过保持字段完整(不对其进行任何计算)来改变查询,而是依赖于改进的优化器,而是对其他值进行(反向)计算。在您的情况下,由GetDate()提供的当前日期。然后查询可以使用字段table1.Date的索引。

所以,你可以使用类似的东西:

SELECT COUNT(*) 
FROM table1
WHERE table1.Date
      BETWEEN
             /* First Day of Current Month */
          AND 
             /* Last Day of Current Month */

您只需要找到能够让您获得当月第一天和最后一天的功能。

此博客文章可以为您提供帮助: sql-server-query-to-find-first-and-last-day-of-current-month/

更好的是,这个StackOverflow问题/答案: simplest-way-to-create-a-date-that-is-the-first-day-of-the-month-given-another-date

我必须测试,但我认为上面的这种微小变化会做:

SELECT COUNT(*) 
FROM table1
WHERE table1.Date 
      >=      /* First Day of Current Month */
        DATEADD(mm, DATEDIFF(mm, 0, GetDate() ), 0) 
  AND table1.Date 
      <       /* First Day of Next Month */
        DATEADD(mm, 1 + DATEDIFF(mm, 0, GetDate() ), 0) 

答案 1 :(得分:0)

您是否尝试使用Local Temporary Table首先插入所有必需的记录?最后,在临时表上进行计算并将其返回。