0

运行这个查询需要 30-40 秒,我需要让它更快。任何帮助表示赞赏。使用下面的视图脚本进行更新。它在 .NET 环境中的 Microsoft SQL Server 2008 上运行。在较小的数据库上需要 3 或 4 秒,但我正在使用的数据库要大得多,而且它正好在 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
4

1 回答 1

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 是更多相关参数的占位符。

于 2013-10-18T18:21:17.563 回答