Performance 使用交叉应用的SQL使查询运行非常缓慢
下面的查询需要35秒才能完成,因此前端应用程序抛出“Timeout expired”错误,我通过增加CommandTimeOut进行了修复,但我的审阅者没有接受修复,因为修复必须在sql查询中完成 下面是我的sql查询Performance 使用交叉应用的SQL使查询运行非常缓慢,performance,sql-server-2008,cross-apply,Performance,Sql Server 2008,Cross Apply,下面的查询需要35秒才能完成,因此前端应用程序抛出“Timeout expired”错误,我通过增加CommandTimeOut进行了修复,但我的审阅者没有接受修复,因为修复必须在sql查询中完成 下面是我的sql查询 select * from SamplesPartners as sp WITH (READUNCOMMITTED) WHERE (EXISTS ( SELECT * FROM SamplesPartners AS sp2 CRO
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
我找不到可以更改和提高性能的地方。我将您的查询更改为:
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
))
我改变这一点:
- 删除
运算符并合并所有或
运算符,以减少对数据的搜索类似的
- 使用
作为一个字段,而不是1
作为多个字段,以减少内存的使用*
- 我将
更改为isDeleted=0x0
,以减少它的类型转换,因为我认为它的类型不是isDeleted=0
,因为您也在表值函数中使用它varbinary
- 我删除last
,因为您正在和isDeleted=0
部分中检查它EXISTS
isDeleted
字段的类型是否确实是varbinary
?删除'OR'运算符并合并所有'LIKE'运算符,结果为零,相信我:)而“isDeleted”类型是“bit”。您刚才提到了替换表值函数,您能详细说明一下吗?