2015-01-21 2 views
0

У меня есть следующая таблица:Хранится производительность процедуры Выберите SQL

CREATE TABLE [dbo].[_tbHRPro](
    [ideID] [int] IDENTITY(-2147483648,1) NOT NULL, 
    [FID] [int] NULL, 
    [myDate] [datetime] NULL, 
    [myTime] [time](7) NULL, 
    [oValue] [decimal](18, 2) NULL, 
    [pValue] [decimal](18, 2) NULL, 
CONSTRAINT [PK__tbHRPro] PRIMARY KEY CLUSTERED 
(
    [ideIDID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

Тогда, я имею следующую хранимую процедуру:

DECLARE @MonthID int = 2; 
DECLARE @Year varchar(5) = '2014'; 
DECLARE @date1 DATE; 
DECLARE @date2 DATE; 

SET @date1 = DATEADD(DAY,-1,DATEADD(MONTH,1,CAST(CAST(@MonthID AS VARCHAR)+'/01/'+CAST(@Year AS VARCHAR)AS DATE))) 
SET @date2 = CAST('01/01/'+CAST(@Year AS VARCHAR)AS DATE) 

SELECT 
      a.ideID 
      , a.FID 
      , b.FC 
      , a.myDate 
      , a.myTime 
      , a.oValue 
      , a.pValue 
     INTO 
      #TEMPX 
     FROM 
      _tbHRPro a 
      INNER JOIN _FC b ON a.FID = b.FID 
     WHERE 
      myDate BETWEEN Dateadd(day, -1, @date2) AND dateadd(day, 1, @date1) 

     ;WITH CTE AS 
      (
       SELECT 
        T1.ideID 
        , T1.FID 
        , T1.FC 
        , T1.myDate 
        , T1.myTime 
        , T1.oValue 
        , CASE WHEN T1.oValue = 0 THEN 0 ELSE T1.oValue - T2.oValue END xValue 
        , T1.pValue 
        , CAST(T1.myDate AS datetime) + CAST(T1.myTime as datetime) oDateTime 
        , (CASE WHEN T1.oValue = 0 THEN 0 ELSE T1.oValue - T2.oValue END) - T1.pValue sDel 
       FROM 
        #TEMPX T1 
        LEFT JOIN #TEMPX T2 on T1.FID = T2.FID 
        AND DATEADD(HOUR, -1, CAST(T1.myDate AS datetime) + CAST(T1.myTime AS datetime)) = CAST(T2.myDate AS datetime) + CAST(T2.myTime AS datetime) 
        LEFT JOIN #TEMPX T3 on T1.FID = T3.FID 
        AND DATEADD(HOUR, 1, CAST(T1.myDate AS datetime) + CAST(T1.myTime AS datetime)) = CAST(T3.myDate AS datetime) + CAST(T3.myTime AS datetime) 
      ) 
     , CTE2 AS 
      (  
       SELECT 
        T1.ideID 
        , T1.FID 
        , T1.FC 
        , T1.myDate 
        , T1.myTime 
        , T1.oValue 
        , CASE WHEN T1.oValue = 0 then (T2.xValue + T3.xValue)/2 ELSE T1.xValue END AS xValue 
        , T1.pValue 
        , (CASE WHEN T1.oValue = 0 then (T2.xValue + T3.xValue)/2 ELSE T1.xValue END) - T1.pValue sDel  
       FROM 
        CTE T1 
        LEFT JOIN CTE T2 ON T1.myDate = T2.myDate 
        AND T1.FID = T2.FID 
        AND DATEADD(HOUR, -1, T1.oDateTime)= T2.oDateTime 
        LEFT JOIN CTE T3 on T1.myDate = T3.myDate and T1.FID = T3.FID 
        AND DATEADD(HOUR, 1, T1.oDateTime)= T3.oDateTime 
      ) 

     SELECT 
      ideID 
      , FID 
      , FC 
      , myDate 
      , myTime 
      , oValue 
      , xValue 
      , pValue 
      , sDel 
     INTO 
      #_vwHRPro 
     FROM 
      CTE2 
     ORDER BY 
      FC 
      , myDate 
      , myTime 

     ;WITH ff AS 
      (
       SELECT 
        FID 
        , FC 
        , DATEADD(hh, - 1, DATEADD(hh, DATEPART(hh, myTime), myDate)) AS newDate 
        , xValue 
       FROM 
        #_vwHRPro 
      ) 

     SELECT 
      A.FID1 
      , A.FC1 
      , A.myDate1 
      , A.totxValue1 
      , B.FID2 
      , B.FC2 
      , B.myDate2 
      , B.totxValue2 
      , C.FID3 
      , C.FC3 
      , C.myDate3 
      , C.totxValue3 
     INTO 
      #_vwpm102 
     FROM 
      (
       SELECT 
        FID AS FID1 
        , FC AS FC1 
        , CAST(newDate AS DATE) AS myDate1 
        , SUM(xValue) AS totxValue1 
       FROM 
        ff 
       WHERE 
        (FC LIKE '%1%') 
       GROUP BY 
        FID 
        , FC 
        , CAST(newDate AS DATE) 
      ) AS A FULL OUTER JOIN 
      (
       SELECT 
        FID AS FID2 
        , FC AS FC2 
        , CAST(newDate AS DATE) AS myDate2 
        , SUM(xValue) AS totxValue2 
       FROM 
        ff 
       WHERE 
        (FC LIKE '%2%') 
       GROUP BY 
        FID 
        , FC 
        , CAST(newDate AS DATE) 
      ) AS B ON A.myDate1 = B.myDate2 
      FULL OUTER JOIN 
      (
       SELECT 
        FID AS FID3 
        , FC AS FC3 
        , CAST(newDate AS DATE) AS myDate3 
        , SUM(xValue) AS totxValue3 
       FROM 
        ff 
       WHERE 
        (FC LIKE '%3%') 
       GROUP BY 
        FID 
        , FC 
        , CAST(newDate AS DATE) 
      ) AS C ON A.myDate1 = C.myDate3 


SELECT * FROM #_vwpm102 order by FC1, myDate1 

я использую временную таблицу, чтобы уменьшить время загрузки данных. Данные огромны, он запущен с 2001 года.

Время загрузки, когда я выполняю хранимую процедуру, составляет 32сек.

Я попытался запустить из окна запросов, он загружается также около 30 секунд. Но поскольку он хранится во временной таблице, второй раз я запускаю.

мне просто нужно выбрать следующее заявление:

SELECT * FROM #_vwpm102 order by FC1, myDate1 

Он загружает так быстро, только 1 сек.

У кого-нибудь есть идея, как минимизировать время загрузки? по крайней мере, менее 10 секунд.

Цените свою помощь и идею. Cheers,

+1

попытайтесь уменьшить свои функции броска ...так как ваш mydate и мое время и т. д. вы бросаете каждый раз .. создайте производный столбец, если вы не можете изменить базовую таблицу. Также создайте индекс NC в столбце FC. – Saravanan

+0

@Saravanan, он уменьшает 5 секунд. Он загрузился 27 секунд. – Haminteu

ответ

1

Для того, чтобы КТР у вас есть «LEFT JOIN #TEMPX T3», но никогда не использовать T3 - удалить его. Есть много столбцов, которые помещаются в таблицы temp, которые никогда не используются - убивайте их.

CAST() стоят дорого, и вы присоединяетесь к ним. Я бы добавил вычисляемый столбец в таблицу _tbHRPro.

ALTER TABLE _tbHRPro 
Add Column myDateTime As CAST(myDate AS datetime) + CAST(myTime as datetime) 

(я уверен, вы будете использовать это для многих других вещей тоже.)

Затем добавить индекс по этому вычисляемого столбца:

CREATE INDEX IDX_tbHRPro_myDateTime ON _tbHRPro(myDateTime) 

Это позволит ускорить процесс много ,

Вместо имеющих колонн имени FC1, FC2, FC3, myDate1, myDate2 и т.д. Я бы есть столбец FCType (возможно, сделать это вычисляемый столбец в таблице _FC.)

ALTER TABLE _FC 
Add Column FCType AS CASE WHEN FC LIKE '%1%' THEN 1 
CASE WHEN FC LIKE '%2%' THEN 2 
CASE WHEN FC LIKE '%3%' THEN 3 END 

Тогда позже вы можете группировать это.

Тогда я думаю, что вы можете упростить SQL для:

 ;WITH CTE AS 
      (
       SELECT 
        me.ideID 
        ,me.FID 
        ,me.myDateTime 
       ,CASE WHEN me.oValue = 0 or me.oValue - behind.oValue = 0 
THEN 
       (CASE WHEN behind.oValue = 0 
         THEN 0 
         ELSE behind.oValue - behind2.oValue END + 
       CASE WHEN infront.oValue = 0 
         THEN 0 
         ELSE me.oValue - infront.oValue END) END/2 
       ELSE .oValue - T2.oValue END xValue 
       FROM _tbHRPro me 
       LEFT JOIN _tbHRPro behind on me.FID = behind.FID 
        AND DATEADD(HOUR, -1, me.myDateTime) = behind.myDateTime 
       LEFT JOIN _tbHRPro behind2 on me.FID = behind2.FID 
        AND DATEADD(HOUR, -2, me.myDateTime) = behind2.myDateTime 
       LEFT JOIN _tbHRPro infront on me.FID = infront.FID 
        AND DATEADD(HOUR, 1, me.myDateTime) = infront.myDateTime 
       WHERE me.myDate 
       BETWEEN Dateadd(day, -1, @date2) AND dateadd(day, 1, @date1) 
      ) 

, а затем сделать ваш набор результатов от этого:

select cast(CTE.myDateTime as Date) theDate, 
_FC.FCType, 
_FC.FC, 
SUM(CTE.xValue) AS totxValue 
from CTE 
inner join _FC 
ON CTE.FID = _FC.FID 
GROUP BY cast(CTE.myDateTime as Date) 
,_FC.FCType 
,_FC.FC 

Не совсем уверен, что правильный расчет для xValue, но вам Получите эту идею. И я не делал таких подробностей, как сделать час, чтобы сделать myDate1.

1

Без схемы таблиц и плана выполнения люди могут только гадать. здесь в запросе: внести некоторые изменения в СП

(1) Use recompilation sp to use statistics fullest. 
(2) Don`t use function in where condition make a column in temp table and then join that column 
(3) FC LIKE '%1%' and FC LIKE '%1%' is this really necessary avoid these kind of condition. 
+0

Я просто добавляю структуру таблицы – Haminteu

+0

(1) перекомпиляция sp? (2) На какой части? Пожалуйста, покажите мне. (3) Мне нужно, чтобы это условие изменилось с вертикального на горизонтальное. – Haminteu

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