2016-07-26 3 views
0

среда SQL Server Management Studio 2008 R2Производная таблица, в которой оптимизация раздел

У меня есть мнение (довольно длинный SQL код, который представляет собой ряд производных таблиц), который используется несколькими различными пользователями, работающими запросов и хранимых процедур на ~ 4000000 записей. Следующий запрос выполняется примерно через 10 минут.

Select * from dbo.[vw_name] 

Я пытаюсь использовать эту же точку зрения, чтобы вытащить информацию для 1 записи, но запрос еще занимает ~ 10 мин:

Select * from dbo.[vw_name] where ln=1234567890 

Кажется, что вид обрабатывает все 4000000 записей и затем применяя мое предложение where. Я смог реплицировать представление в функцию с табличной оценкой и увеличить время запроса до ~ 10 секунд на одной записи (я предполагаю, потому что мне удалось вставить предложение where в первую производную таблицу, а не в конец). Любые мысли о том, как заставить оптимизатора сначала рассмотреть предложение where при запросе представления?

Добавление Просмотр запроса:

SELECT  AsOfDate=GETDATE() 
     ,A1.* 
     ,Onsite_Flag= CASE 
         WHEN A1.[columnname]=1 AND A1.[columnname]=0 THEN 1 
         WHEN A1.[columnname]=5 AND A1.[columnname]=0 THEN 1 
         WHEN A1.[columnname] IN (12,31,33,34,35,38,52,54,59) THEN 1 
         ELSE 0 
         END 
     ,A1.Allowable_Flag 
     ,Achieved_Flag= CASE 
         WHEN A1.[columnname]=1 THEN 
          CASE 
          WHEN A1.[columnname] LIKE 'name%' 
          AND A1.[columnname]>=A1.[columnname] 
          AND (A1.[columnname] LIKE '%LOL%' OR A1.[columnname]='test') THEN 1 
          WHEN A1.[columnname]='qwerw' AND A1.[columnname]=4 THEN 1 
          WHEN A1.[columnname]='aerr33' AND A1.[columnname]=4 THEN 1 
          WHEN A1.[columnname]='asdf45' AND A1.[columnname] IS NOT NULL THEN 1 
          ELSE 0 
          END 
         ELSE 0 
         END 
     ,IM_Flag= CASE 
        WHEN A1.[columnname] IN(12,38) THEN 1 
        WHEN A1.[columnname]=1 AND A1.[columnname]=24 THEN 1 
        ELSE 0 
        END 
FROM  (SELECT  [columnname].... 
        ,[Name]=LTRIM(RTRIM(V1.A1FNAM)) + ' ' + LTRIM(RTRIM(V1.A1LNAM)) 
        ,LocationType= CASE WHEN LH1.[columnname]=2 THEN nLT.[columnname] ELSE LT.[columnname] END 
        ,LocationTypeID=CASE WHEN LH1.[columnname]=2 THEN nLT.[columnname] ELSE LT.[columnname] END 
        ,Location=CASE 
           WHEN DLD1.[columnname] IS NULL THEN DLD1.[columnname] 
           WHEN LH1.[columnname] IN (2,8) THEN DLD1.[columnname] + ' - ' + DLD2.[columnname] 
           ELSE DLD1.[columnname] 
           END 
        ,Allowable_Flag= CASE 
             WHEN CU1.[columnname]='1234' THEN 1 
             WHEN FCM.[columnname]='Y' THEN 0 
             WHEN MLD.[columnname]='24' THEN 0 
             WHEN INV.[columnname] LIKE '436573456%' THEN 1 
             WHEN INV.[columnname] LIKE '4526%' THEN 1 
             WHEN DSR.[columnname]='1020' THEN 1 
             ELSE 0 
             END 
        ,RN=ROW_NUMBER()OVER(PARTITION BY L.LoanNumber ORDER BY (CASE WHEN DM.Departments_ID=24 THEN 1 ELSE 0 END) DESC,LH1.LocationDate DESC) 
     FROM  server_name_3.dbo.[tablename] DSR 
     LEFT JOIN .... 
     OUTER APPLY SERVER_name_2.dbo.fnc_DT (LH1.[columnname], LH1.[columnname]) DLD1 
     OUTER APPLY SERVER_name_2.dbo.fnc_DT (DLD1.[columnname], DLD1.[columnname]) DLD2 
     LEFT JOIN (SELECT field1, field2,... 
        FROM server_name_3.dbo.SRVDSR DSR 
        LEFT JOIN ... 
        INNER JOIN (SELECT field1, MAX(field2) as field2 FROM SERVERNAME1.dbo.[tablename] WHERE field3=157 GROUP BY field1) CUO ON CUO.field1=R.field1 
        GROUP BY DSR.field1 
        ) CP_Req ON DSR.field1=CP_Req.field1 

     ) A1  
WHERE A1.RN=1 
+1

См http://www.databasejournal.com/features/mssql/article.php/3867651/SQL-Server-Indexed-Views.htm –

+0

Я не могу SCHEMABIND мнение, как она попадает несколько баз данных, добавленных – Czar

ответ

0

(1) Убедитесь в том, что есть индекс на поле "LN". (2) Отправьте запрос вида, и мы увидим, что он может быть оптимизирован - обфускать поля, если вам нужно в целях безопасности.

+0

вид SQL выше – Czar

0

Если этот номер строки, который вы ищете, находится из этой функции ROW_NUMBER, тогда да, он должен будет произвести все результаты, прежде чем он сможет отправить вам одну запись. Вы можете попробовать сделать запрос более детерминированным путем удаления GETDATE и ROW_NUMBER с точки зрения себя и вместо того, чтобы включить эти поля в запросе в представлении:

; WITH DateNow 
AS ( 
    SELECT DateNow = GETDATE() 
    ) 
SELECT d1.DateNow 
    , v1.* 
    , ROW_NUMBER() OVER... 
FROM YourView v1 
    , DateNow d1 

Это будет по-прежнему должны производить весь результат, но сам вид может быть быстрее. Я могу дать вам общий совет, если это поможет. Поиск с двойным подстановочным знаком,% foo%, является убийцей производительности, но я знаю, что вы часто зацикливаетесь на нем. Вы могли бы обратить внимание на то, чтобы превратить эти производные таблицы в индексированные представления или добавить много сравнения строк в постоянные вычисленные столбцы. Я думаю, что лучшим решением, если данные могут быть несколько устаревшими, является запуск этого запроса один раз в ночное время и вставка результатов в одну таблицу, датамарт, которая будет очень быстрой для запроса.

Смежные вопросы