减少 SQL 查询的执行时间
Decrease execution time of SQL query
我有一个关于处理和提高查询效率同时保持其准确性的问题。在显示查询之前,我想指出它的一些基础知识。
我有一个案例可以操纵 where
-子句来获取父项的所有子项。基本上我有两种类型的数据需要显示;红色和绿色类型。红色类型有一列 (TRK_TrackerGroup_LKID2
) 默认设置为 NULL
,而绿色数据在该列中有一个值(范围从 5-7) .
我的问题是我需要提取两种类型的数据以准确计算视图中未解决问题的数量,但这样做(通过添加大小写)执行时间从 < 1秒 到 15 秒。
这是查询(提到的案例):
SELECT TS.id AS TrackerStartDateID,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
Count(TF.id) AS Cnt
FROM [dbo].[trk_startdate] TS
INNER JOIN [dbo].[trk_startdatemap] TSM
ON TS.id = TSM.trk_startdateid
AND TSM.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures] TF
ON TF.trk_startdateid = TS.id
AND TF.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK
ON TFLK.id = TF.trk_feature_lkid
WHERE TS.deletedflag = 0
AND TF.applicabletoproject = 1
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
AND TF.datestamp = (SELECT Max(TF2.datestamp)
FROM [dbo].[trk_trackerfeatures] TF2
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK2
ON TFLK2.id = TF2.trk_feature_lkid
WHERE TF.trk_startdateid = TF2.trk_startdateid
AND TFLK2.trk_trackergroup_lkid = TFLK.trk_trackergroup_lkid)
GROUP BY TS.id,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
TF.datestamp
从每个子组获取最新插入的数据集(使用 DateStamp)的意义上说,它的功能与 'parent' 相同。这是稍后在 SSRS 报告中生成父报告所必需的,但目前我的问题(如上所述)是执行时间。
我想听听是否有关于如何在保持查询准确性的同时减少执行时间的任何建议。
预期输出:
没有案例我得到这个:
您的查询中最有问题的部分似乎是相关子查询,因为您必须为每个可能的行调用它。
你应该先优化这个。为此,您可以添加引擎可用于快速计算每行值的索引。
根据您的查询,我会将这两个索引相加:
在 Table trackerfeatures
上,索引字段:trk_startdateid, datestamp
在 Table trk_trackerfeatures_lk
上,索引字段:id, trk_trackergroup_lkid
你的问题是这个条件不能用INDEX
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
试着改成
AND ( TF.readyforwork = 0 and TF.trk_trackerstatus_lkid2 IS NULL
OR TF.readyforwork = 1 and TF.trk_trackerstatus_lkid2 IS NOT NULL
)
但是您应该再次检查 EXPLAIN ANALIZE
以测试您的查询是否正在使用索引。
我有一个关于处理和提高查询效率同时保持其准确性的问题。在显示查询之前,我想指出它的一些基础知识。
我有一个案例可以操纵 where
-子句来获取父项的所有子项。基本上我有两种类型的数据需要显示;红色和绿色类型。红色类型有一列 (TRK_TrackerGroup_LKID2
) 默认设置为 NULL
,而绿色数据在该列中有一个值(范围从 5-7) .
我的问题是我需要提取两种类型的数据以准确计算视图中未解决问题的数量,但这样做(通过添加大小写)执行时间从 < 1秒 到 15 秒。
这是查询(提到的案例):
SELECT TS.id AS TrackerStartDateID,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
Count(TF.id) AS Cnt
FROM [dbo].[trk_startdate] TS
INNER JOIN [dbo].[trk_startdatemap] TSM
ON TS.id = TSM.trk_startdateid
AND TSM.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures] TF
ON TF.trk_startdateid = TS.id
AND TF.deletedflag = 0
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK
ON TFLK.id = TF.trk_feature_lkid
WHERE TS.deletedflag = 0
AND TF.applicabletoproject = 1
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
AND TF.datestamp = (SELECT Max(TF2.datestamp)
FROM [dbo].[trk_trackerfeatures] TF2
INNER JOIN [dbo].[trk_trackerfeatures_lk] TFLK2
ON TFLK2.id = TF2.trk_feature_lkid
WHERE TF.trk_startdateid = TF2.trk_startdateid
AND TFLK2.trk_trackergroup_lkid = TFLK.trk_trackergroup_lkid)
GROUP BY TS.id,
TSM.mappingtypeid,
TSM.maptoid,
TFLK.trk_trackergroup_lkid,
TF.datestamp
从每个子组获取最新插入的数据集(使用 DateStamp)的意义上说,它的功能与 'parent' 相同。这是稍后在 SSRS 报告中生成父报告所必需的,但目前我的问题(如上所述)是执行时间。
我想听听是否有关于如何在保持查询准确性的同时减少执行时间的任何建议。
预期输出:
没有案例我得到这个:
您的查询中最有问题的部分似乎是相关子查询,因为您必须为每个可能的行调用它。
你应该先优化这个。为此,您可以添加引擎可用于快速计算每行值的索引。
根据您的查询,我会将这两个索引相加:
在 Table
trackerfeatures
上,索引字段:trk_startdateid, datestamp
在 Table
trk_trackerfeatures_lk
上,索引字段:id, trk_trackergroup_lkid
你的问题是这个条件不能用INDEX
AND TF.readyforwork = CASE -- HERE IS THE PROBLEM
WHEN TF.trk_trackerstatus_lkid2 IS NULL THEN 0
ELSE 1
END
试着改成
AND ( TF.readyforwork = 0 and TF.trk_trackerstatus_lkid2 IS NULL
OR TF.readyforwork = 1 and TF.trk_trackerstatus_lkid2 IS NOT NULL
)
但是您应该再次检查 EXPLAIN ANALIZE
以测试您的查询是否正在使用索引。