0

下面的查询需要 35 秒才能完成,所以前端应用程序抛出“超时过期”错误,我通过增加 CommandTimeOut 来修复,但我的审阅者不接受修复,因为修复必须在 sql 查询中完成。

下面是我的 sql 查询

select * from SamplesPartners as sp WITH (READUNCOMMITTED) WHERE (EXISTS
(
    SELECT      *
    FROM        SamplesPartners  AS sp2
    CROSS APPLY SE_GetCurrentParentContainersForItem(sp2.samplePartnerSqlId, sp2.samplePartnerIncId, 2, 293) AS CC
    JOIN        dbo.Containers   AS C ON    C.containerSqlId = CC.containerSqlId
                                        AND C.containerIncId = CC.containerIncId
                                        AND C.isDeleted      = 0x0
    LEFT JOIN   dbo.Shipments    AS S ON    S.containerSqlId = C.containerSqlId
                                        AND S.containerIncId = C.containerIncId
                                        AND S.isDeleted      = 0x0
    LEFT JOIN   dbo.Destinations AS D ON    D.containerSqlId = C.containerSqlId
                                        AND D.containerIncId = C.containerIncId
                                        AND D.isDeleted      = 0x0
    WHERE       sp2.samplePartnerSqlId = sp.samplePartnerSqlId
    AND         sp2.samplePartnerIncId = sp.samplePartnerIncId
    AND         (
                    C.containerCode   LIKE '%test%'
                OR  C.containerName   LIKE '%test%'
                OR  S.trackingNumber  LIKE '%test%'
                OR  D.destinationName LIKE '%test%'
                )   
    AND         sp2.isDeleted = 0x0
)) and isDeleted=0

下面是函数

ALTER FUNCTION [dbo].[SE_GetCurrentParentContainersForItem]
(
    @itemSqlId          SMALLINT,
    @itemIncId          INT,
    @itemMetaTableSqlId SMALLINT,
    @itemMetaTableIncId INT
)
RETURNS TABLE

AS

RETURN
WITH      ContainersMetaTable AS (
           -- Returns only 1 record.
           SELECT    metaTableSqlId,metaTableIncId FROM dbo.MetaTables WHERE metaTableName = 'Containers'),
          ContainerSubtree AS (
           -- Anchor member.
           SELECT    containerSqlId,containerIncId,0 AS lvl
           FROM      dbo.ContainersContents
           WHERE     contentSqlId          = @itemSqlId
             AND     contentIncId          = @itemIncId
             AND     contentMetaTableSqlId = @itemMetaTableSqlId
             AND     contentMetaTableIncId = @itemMetaTableIncId
             AND     isDeleted             = 0

           UNION ALL

           -- Recursive member.
           SELECT    cc.containerSqlId,
                     cc.containerIncId,
                     sub.lvl + 1        AS lvl
           FROM      ContainersMetaTable    AS cmt,
                     dbo.ContainersContents AS cc
           JOIN      ContainerSubtree       AS sub ON  cc.contentSqlId = sub.containerSqlId
                                                   AND cc.contentIncId = sub.containerIncId
                                                   AND cc.isDeleted    = 0
           WHERE     cc.contentMetaTableSqlId = cmt.metaTableSqlId
             AND     cc.contentMetaTableIncId = cmt.metaTableIncId             
          )
SELECT    containerSqlId,
          containerIncId,
          lvl
FROM      ContainerSubtree

我找不到可以改变和提高性能的地方。

4

1 回答 1

0

我将您的查询更改为:

SELECT * 
FROM SamplesPartners AS sp WITH (READUNCOMMITTED) 
WHERE (EXISTS (
    SELECT      1
    FROM        SamplesPartners  AS sp2
    CROSS APPLY SE_GetCurrentParentContainersForItem(sp2.samplePartnerSqlId, sp2.samplePartnerIncId, 2, 293) AS CC
    JOIN        dbo.Containers   AS C ON    C.containerSqlId = CC.containerSqlId
                                        AND C.containerIncId = CC.containerIncId
                                        AND C.isDeleted      = 0
    LEFT JOIN   dbo.Shipments    AS S ON    S.containerSqlId = C.containerSqlId
                                        AND S.containerIncId = C.containerIncId
                                        AND S.isDeleted      = 0
    LEFT JOIN   dbo.Destinations AS D ON    D.containerSqlId = C.containerSqlId
                                        AND D.containerIncId = C.containerIncId
                                        AND D.isDeleted      = 0
    WHERE       sp2.samplePartnerSqlId = sp.samplePartnerSqlId
    AND         sp2.samplePartnerIncId = sp.samplePartnerIncId
    AND         (C.containerCode + ':' + C.containerName + ':' + S.trackingNumber + ':' + D.destinationName) LIKE '%test%'
    AND         sp2.isDeleted = 0
    )) 

我改变这个:

  • 删除OR运算符并合并所有LIKE运算符以减少对数据的搜索。
  • 使用1一个字段而不是*多个字段来减少内存的使用。
  • isDeleted = 0x0改为isDeleted = 0减少它的类型转换,因为我认为它的类型不像varbinary您在表值函数中使用它那样。
  • 我最后删除AND isDeleted = 0是因为您正在零件内部检查它EXISTS
于 2015-06-01T10:40:10.500 回答