使用Union All优化SQL查询

时间:2010-11-09 01:03:27

标签: sql-server-2005 tsql query-optimization

我有一个查询,其中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

查看1定义

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

查看2定义

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

查看3定义

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 个答案:

答案 0 :(得分:2)

  

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

但观点中是否有加入?这些观点有没有共同的表格?

如果没有查看查询以及视图所代表的查询,那么很少有人可以提供有价值的查询。

答案 1 :(得分:1)

  

“估计的子树成本”是2.12357,我   总是假设它是否超过1   这是一个非常缓慢的查询

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

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

尽管如此,为了放松修辞,更高的子树成本可能支持您的想法可能可以改进查询。

  

仅有表扫描   聚集索引扫描

改善查询可能是一个更大的机会,就是看看为什么存在聚集索引扫描。聚集索引扫描等同于表扫描。正在扫描包含表数据的整个聚簇索引。必须评估表中的所有行,还是表明性能改进机会?

答案 2 :(得分:0)

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

真的分析和识别sql改进会更好,但你没有发布sql,所以我们无法帮助你。