2013-10-18 30 views
0

運行此查詢需要30-40秒,我需要使其更快。任何幫助表示讚賞。使用下面的視圖腳本更新。它在.NET環境中運行在Microsoft SQL Server 2008上。它需要3或4秒鐘在一個較小的分貝,但我正在使用的分貝更大,它正好在SQL超時邊界。需要速度(ier sql查詢)

WITH TEMP As 
    (SELECT * 
     FROM (SELECT lease_number         AS 'lease_number', 
         facility          AS 'facility', 
         Lease_Name         AS 'Lease_Name', 
         lease_start_date        AS 'lease_start_date', 
         lease_end_date        AS 'lease_end_date', 
         slschedule_id        AS 'slschedule_id', 
         type_id          AS 'type_id', 
         lease_id          AS 'lease_id', 
         property_id         AS 'property_id', 
         VW_FND_LA_PORT_SL.row_id      AS 'row_id', 
         ROW_NUMBER() OVER (ORDER BY VW_FND_LA_PORT_SL.row_id ASC) ROW_NBR 
       FROM VW_FND_LA_PORT_SL 
       WHERE (classfication = 1 
          AND slschedule_id = 1 
          AND is_dirty = 0 
          AND is_new = 1)) AS ROWNUM_APPENDED), 

    countfinder AS (SELECT Count(*) AS [rowcount] FROM TEMP) 

SELECT *, 
     (SELECT [rowcount] FROM countfinder) [totalrowcount] 
FROM TEMP 
WHERE ROW_NBR >= (1 - (1 - 1)%10) 
    AND ROW_NBR < (1 - (1 - 1)%10 + 10) 

這裏的景觀:

CREATE VIEW [dbo].[vw_FND_LA_PORT_SL] 
AS 
SELECT DISTINCT(L.lease_id), 
       L.lease_number, 
       L.name AS Lease_Name, 
       L.lease_start_date, 
       L.lease_end_date, 
       F.name AS facility, 
       L.row_id, 
       L.property_id, 
       L.heldby_id, 
       EC.slschedule_id, 
       S.type_id, 
       CASE 
       WHEN dbo.Udf_isleaseoperational(L.lease_id) = '1' THEN 1 
       ELSE 2 
       END AS classfication, 
       CASE 
       WHEN (SELECT dirty_flag 
         FROM la_tbl_slschedule_calc_detail AS D 
         WHERE D.lease_id = L.lease_id 
           AND D.slschedule_id = S.slschedule_id 
           AND isdeleted = 0) = 1 THEN 1 
       ELSE 0 
       END AS is_dirty, 
       CASE 
       WHEN (CASE 
          WHEN dbo.Udf_isleaseoperational(L.lease_id) = '1' THEN 
          (SELECT Count(*) 
          FROM 
         la_tbl_slschedule_calculation AS O 
          WHERE 
          O.lease_id = L.lease_id 
          AND O.slschedule_id = S.slschedule_id 
          AND isdeleted = 0) 
          ELSE (SELECT Count(*) 
           FROM la_tbl_slcapitalschedule_calc AS C 
           WHERE C.lease_id = L.lease_id 
             AND C.slschedule_id = S.slschedule_id 
             AND isdeleted = 0) 
         END) > 0 THEN 0 
       ELSE 1 
       END AS is_new 
FROM dbo.la_tbl_lease AS L 
     INNER JOIN dbo.vw_fnd_tlu_facility AS F 
       ON L.property_id = F.facilitypk 
     INNER JOIN la_tbl_expense AS E 
       ON L.lease_id = E.lease_id 
     INNER JOIN la_tbl_slschedule_expcategory AS EC 
       ON E.expense_category_id = EC.expense_category_id 
     INNER JOIN la_tbl_slschedule AS S 
       ON S.slschedule_id = EC.slschedule_id 
     INNER JOIN la_tlu_held_by AS H 
       ON L.heldby_id = H.heldby_id 
WHERE L.isdeleted = 0 
     AND E.isdeleted = 0 
     AND EC.isdeleted = 0 
     AND S.isdeleted = 0 
     AND (dbo.Udf_getnumberofleaseterms(L.lease_id) > 0) 
     AND H.system_type <> '3' 

GO 
+0

估計的執行計劃是什麼樣的? – Elias

+0

VW_FND_LA_PORT_SL是一個視圖嗎?如果是這樣的定義是什麼? –

+0

嘗試使用s子查詢而不是CTE。 –

回答

0

沒有看到一個執行計劃或正在發生的事情與VW_FND_LA_PORT_SL(看起來很像一個視圖)...
該位:

WHERE ROW_NBR >= (1 - (1 - 1)%10) 
     AND ROW_NBR < (1 - (1 - 1)%10 + 10) 

實際上是:

TOP 10 
... 
ORDER BY 
    VW_FND_LA_PORT_SL.row_id ASC 

而且總排子選擇可能是:

COUNT(*) OVER() AS [rowcount] -- tsk tsk, using a reserved word for a column name ;) 

所以看起來你可能混淆了優化。也許試試這個:

SELECT 
    * 
FROM 
    (
     SELECT 
      lease_number AS 'lease_number' 
      , facility AS 'facility' 
      , Lease_Name AS 'Lease_Name' 
      , lease_start_date AS 'lease_start_date' 
      , lease_end_date AS 'lease_end_date' 
      , slschedule_id AS 'slschedule_id' 
      , type_id AS 'type_id' 
      , lease_id AS 'lease_id' 
      , property_id AS 'property_id' 
      , VW_FND_LA_PORT_SL.row_id AS 'row_id' 
      , ROW_NUMBER() OVER (ORDER BY VW_FND_LA_PORT_SL.row_id ASC) ROW_NBR 
      , COUNT(*) OVER() [rowcount] 
     FROM 
      VW_FND_LA_PORT_SL 
     WHERE 
      (
       classfication = 1 
       AND slschedule_id = 1 
       AND is_dirty = 0 
       AND is_new = 1 
      ) 
    ) x 
WHERE ROW_NBR BETWEEN 1 AND 10 

可能爲您節省一兩傳過來的設定。這取決於優化器自行制定多少混淆。當然,你所有的時間都可以用在這個觀點上。不能說沒有執行計劃。我使用的是BETWEEN而不是TOP 10,因爲原始where子句中的某些1是更多相關參數的佔位符。