Sql server 2005 使用Union All优化SQL查询

Sql server 2005 使用Union All优化SQL查询,sql-server-2005,tsql,query-optimization,Sql Server 2005,Tsql,Query Optimization,我有一个查询,其中有4个选择查询,由Union All连接以返回一个结果集,它们是非常复杂的选择查询,但不涉及连接,它们实际上从2个不同的视图中进行选择。我只是想优化一下,但不确定从哪里开始。“实际执行计划”是说“估计子树成本”是2.12357,我总是假设如果它超过1,那么它是一个非常慢的查询?这是正确的假设吗?我还检查了整个计划,没有表扫描,只有聚集索引扫描和聚集索引查找,我再次假设它们是可以的?然而,有很多散列匹配。无论如何,这个查询将运行很多次,因此我希望它尽可能优化。希望这有点道理 好的

我有一个查询,其中有4个选择查询,由Union All连接以返回一个结果集,它们是非常复杂的选择查询,但不涉及连接,它们实际上从2个不同的视图中进行选择。我只是想优化一下,但不确定从哪里开始。“实际执行计划”是说“估计子树成本”是2.12357,我总是假设如果它超过1,那么它是一个非常慢的查询?这是正确的假设吗?我还检查了整个计划,没有表扫描,只有聚集索引扫描和聚集索引查找,我再次假设它们是可以的?然而,有很多散列匹配。无论如何,这个查询将运行很多次,因此我希望它尽可能优化。希望这有点道理

好的,SQL看起来像这样

CREATE PROCEDURE [dbo].[CompareFiles] -- Add the parameters for the stored procedure here
@VersionID int, 
@SyncRequestID int,     
@RegionID int, 
@LanguageID int 
AS
BEGIN

SELECT 'Delete' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View1
WHERE NOT EXISTS(SELECT 1 FROM View2 where View2.FullPath = View1.FullPath 
AND View2.VersionId = @VersionID
AND View2.RegionID = @RegionID 
AND View2.LanguageID = @LanguageID
)
AND View1.SyncRequestID = @SyncRequestID

UNION ALL 

SELECT 'Add' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer,FileSize FROM View2  
WHERE NOT EXISTS(SELECT 1 FROM View1 where View1.FullPath = View2.FullPath AND View1.SyncRequestID = @SyncRequestID)
AND 
View2.VersionId = @VersionID
AND View2.RegionID = @RegionID
AND View2.LanguageID = @LanguageID

UNION ALL 

SELECT 'Delete' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View2 
WHERE EXISTS
(
    SELECT 1 FROM View2 fd2 
    WHERE 
        View2.FullPath = fd2.FullPath AND fd2.VersionID = @VersionID
AND 
    View2.FileNameOnServer <> fd2.FileNameOnServer 
AND 
    fd2.RegionID = @RegionID
AND 
    fd2.LanguageID = @LanguageID 
)
AND 
    View2.VersionId = (SELECT VersionID FROM SyncRequest WHERE SyncRequestID = @SyncRequestID)
AND 
    View2.RegionID = @RegionID
AND 
    View2.LanguageID = @LanguageID

UNION ALL

SELECT 'Add' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View2 
WHERE EXISTS
(
SELECT 1 FROM View2 fd2 
WHERE 
    View2.FullPath = fd2.FullPath AND fd2.VersionID = (SELECT VersionID FROM SyncRequest WHERE SyncRequestID = @SyncRequestID)
AND 
    View2.FileNameOnServer <> fd2.FileNameOnServer 
AND 
    fd2.RegionID = @RegionID
AND 
    fd2.LanguageID = @LanguageID 
)
AND 
    View2.VersionId = @VersionID
AND 
    View2.RegionID = @RegionID
AND 
    View2.LanguageID = @LanguageID

END
视图2定义

SELECT DISTINCT fqp.Path + '/' + ISNULL(f.Name, '') + ISNULL(f.Extension, '') AS FullPath, fl.LanguageID, fr.RegionID, f.FileID, dbo.CIT_APD_Versions.ApID, f.FileNameOnServer, dbo.Versions.VersionID, (CASE WHEN FileNameOnServer IS NULL THEN 'Folder' ELSE 'File' END) AS Type, f.FileSize
FROM dbo.FileRegions AS fr 
RIGHT OUTER JOIN dbo.Files AS f 
    INNER JOIN dbo.FilePaths AS fp ON fp.FileID = f.FileID ON fr.FileID = f.FileID 
    LEFT OUTER JOIN dbo.FileLanguages AS fl ON fl.FileID = f.FileID 
    LEFT OUTER JOIN dbo.RoleFiles AS fro ON fro.FileID = f.FileID 
    RIGHT OUTER JOIN dbo.Versions 
        INNER JOIN dbo.View3 AS fqp ON dbo.VersionID = fqp.VersionID ON fqp.PathID = fp.PathID
SELECT     '//' + dbo.CIT_APD_SyncRequestFiles.FullPath AS FullPath, NULL AS LanguageID, NULL AS RegionID, NULL AS FileID, NULL AS ApID, 
                  dbo.SyncRequest.VersionID, '' AS FileNameOnServer, '' AS Type, NULL AS FileSize, dbo.SyncRequestFiles.SyncRequestID
FROM dbo.SyncRequestFiles 
INNER JOIN dbo.CIT_APD_SyncRequest ON dbo.SyncRequestFiles.SyncRequestID = dbo.SyncRequest.SyncRequestID
WITH Parent AS (SELECT PathID, ParentPathID, VersionID, CONVERT(varchar(128), Path) AS Path
FROM dbo.Paths AS ParentPaths
WHERE (ParentPathID = 0)
UNION ALL
SELECT ChildPaths.PathID, ChildPaths.ParentPathID, ChildPaths.VersionID, CONVERT(varchar(128), Parent.Path + '/' + ChildPaths.Path) AS Path
FROM dbo.Paths AS ChildPaths 
INNER JOIN Parent ON Parent.PathID = ChildPaths.ParentPathID)

SELECT PathID, ParentPathID, VersionID, Path
FROM Parent
视图3定义

SELECT DISTINCT fqp.Path + '/' + ISNULL(f.Name, '') + ISNULL(f.Extension, '') AS FullPath, fl.LanguageID, fr.RegionID, f.FileID, dbo.CIT_APD_Versions.ApID, f.FileNameOnServer, dbo.Versions.VersionID, (CASE WHEN FileNameOnServer IS NULL THEN 'Folder' ELSE 'File' END) AS Type, f.FileSize
FROM dbo.FileRegions AS fr 
RIGHT OUTER JOIN dbo.Files AS f 
    INNER JOIN dbo.FilePaths AS fp ON fp.FileID = f.FileID ON fr.FileID = f.FileID 
    LEFT OUTER JOIN dbo.FileLanguages AS fl ON fl.FileID = f.FileID 
    LEFT OUTER JOIN dbo.RoleFiles AS fro ON fro.FileID = f.FileID 
    RIGHT OUTER JOIN dbo.Versions 
        INNER JOIN dbo.View3 AS fqp ON dbo.VersionID = fqp.VersionID ON fqp.PathID = fp.PathID
SELECT     '//' + dbo.CIT_APD_SyncRequestFiles.FullPath AS FullPath, NULL AS LanguageID, NULL AS RegionID, NULL AS FileID, NULL AS ApID, 
                  dbo.SyncRequest.VersionID, '' AS FileNameOnServer, '' AS Type, NULL AS FileSize, dbo.SyncRequestFiles.SyncRequestID
FROM dbo.SyncRequestFiles 
INNER JOIN dbo.CIT_APD_SyncRequest ON dbo.SyncRequestFiles.SyncRequestID = dbo.SyncRequest.SyncRequestID
WITH Parent AS (SELECT PathID, ParentPathID, VersionID, CONVERT(varchar(128), Path) AS Path
FROM dbo.Paths AS ParentPaths
WHERE (ParentPathID = 0)
UNION ALL
SELECT ChildPaths.PathID, ChildPaths.ParentPathID, ChildPaths.VersionID, CONVERT(varchar(128), Parent.Path + '/' + ChildPaths.Path) AS Path
FROM dbo.Paths AS ChildPaths 
INNER JOIN Parent ON Parent.PathID = ChildPaths.ParentPathID)

SELECT PathID, ParentPathID, VersionID, Path
FROM Parent
谢谢

…它们是非常复杂的选择查询,但不涉及连接,它们实际上从两个不同的视图中进行选择

但是,这些观点是否有共同点?这些视图有共同的表吗

如果看不到查询和视图所代表的查询,几乎没有人能提供有价值的信息

…它们是非常复杂的选择查询,但不涉及连接,它们实际上从两个不同的视图中进行选择

但是,这些观点是否有共同点?这些视图有共同的表吗


如果看不到查询以及视图所代表的查询,那么几乎没有人能够提供有价值的查询。

通过索引优化向导运行查询,这可以告诉您哪些索引可以提供帮助


实际上,最好是分析和确定sql的改进,但是您没有发布sql,因此我们无法帮助您。

通过索引优化向导运行查询,这可以告诉您哪些索引可以提供帮助

实际上,最好是分析和确定sql的改进,但是您没有发布sql,因此我们无法帮助您

“估计子树成本”为2.12357,I 始终假定如果超过1,则 这是一个相当慢的查询

子树成本不能单独用于评估性能。它用于比较执行相同任务的不同查询。因此,假设高成本表示查询性能差是不可靠的

您必须回答“查询是否在可接受的时间内返回结果?”

综上所述,为了放松修辞,较高的子树成本可能支持您的想法,即可能查询可以改进

没有表格扫描,只有 聚集索引扫描

改进查询的一个更大的机会是了解为什么会有聚集索引扫描。聚集索引扫描相当于表扫描。正在扫描包括表数据的整个聚集索引。是否必须评估表中的所有行,或者这是性能改进机会的迹象

“估计子树成本”为2.12357,I 始终假定如果超过1,则 这是一个相当慢的查询

子树成本不能单独用于评估性能。它用于比较执行相同任务的不同查询。因此,假设高成本表示查询性能差是不可靠的

您必须回答“查询是否在可接受的时间内返回结果?”

综上所述,为了放松修辞,较高的子树成本可能支持您的想法,即可能查询可以改进

没有表格扫描,只有 聚集索引扫描


改进查询的一个更大的机会是了解为什么会有聚集索引扫描。聚集索引扫描相当于表扫描。正在扫描包括表数据的整个聚集索引。必须对表中的所有行进行评估,还是这表明存在性能改进机会?

没有足够的信息来回答……您的视图可能包含联接。没有连接的视图没有什么价值(它是一个表!),除非在某些特定情况下,例如隐藏列(授权)抱歉,你说得对,我会清理SQL并将其发布,因为注释有点宽泛,Mitch。由于性能原因,对数据进行水平分区的视图非常有价值。同样,我一直在视图中透视和取消透视数据,以便在odbc链接的电子表格中使用。@Coesy:很好,但是视图定义在哪里?没有足够的信息来回答……您的视图可能包含联接。没有连接的视图没有什么价值(它是一个表!),除非在某些特定情况下,例如隐藏列(授权)抱歉,你说得对,我会清理SQL并将其发布,因为注释有点宽泛,Mitch。由于性能原因,对数据进行水平分区的视图非常有价值。同样,我一直在视图中透视和取消透视数据,以便在odbc链接的电子表格中使用。@Coesy:很好,但是视图定义在哪里?