Как улучшить производительность недетерминированной функции столбца в предложении where или объединении? - PullRequest
4 голосов
/ 04 июня 2011

Я хотел бы улучшить производительность запроса, в котором есть предложение 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) - «УДАЛЕНО» DATETIME и индексирование

Какие есть варианты повышения производительности?

Ответы [ 2 ]

3 голосов
/ 04 июня 2011

Помимо недетерминированной функции, проблема, которую я вижу, состоит в том, что вы делаете вычисления на поле.Это (обычно) делает любой индекс в поле непригодным для запроса.

Второй абзац этой ссылки ( Десять распространенных ошибок программирования SQL (функции для индексированных столбцов в предикатах) ) предоставляет более подробную информацию о том, когда это происходит, как этого избежать и как иногда оптимизаторы могут использовать индексы, несмотря на использование функций.

Короче говоря, вместо того, чтобы полагаться на улучшенные оптимизаторы, часто можноизмените запрос, оставив поле без изменений (без каких-либо вычислений на нем), но вместо этого выполнив (обращенные) вычисления с другими значениями.В вашем случае на текущую дату, которая предоставляется 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-month-/ /

Еще лучше, этот вопрос / ответ StackOverflow: самый простой способ создать дату, которая является первым днем ​​днямесяц, данный, другая дата

Я должен буду проверить, но я думаю, что это небольшое изменение вышеупомянутого сделает:

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) 
0 голосов
/ 04 июня 2011

Вы пытались использовать Локальную временную таблицу для первой вставки всех необходимых записей?Наконец, сделайте расчеты по временной таблице и верните ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...