【问题标题】:Is it a valid way to optimize the stored procedure in SQL Server它是优化 SQL Server 中存储过程的有效方法吗
【发布时间】:2016-03-09 04:34:11
【问题描述】:

我有一个名为Optimized_GetArticlePost 的存储过程,我想对其进行优化。

当前存储过程:

CREATE PROCEDURE [dbo].[Optimized_GetArticlePost]            
    (@PostID int)
    --[Optimized_GetArticlePost] 
AS                                  
BEGIN 
    SET NOCOUNT ON;                                  

    //declare all the required variables.. 

    -- LIST ALL ATTACHMENTS                                           
    SELECT [FileName] 
    FROM CS_PostAttachments                  
    WHERE contenttype LIKE 'audio/mpeg' 
      AND FILENAME LIKE '%.mp3' 
      AND isremote = 1 
      AND postid = @Postid ------returns a seperate table

    --GET THE FB FEED IMAGES FOR THIS  POST
    SELECT ImageURL 
    FROM PostFBImageURL 
    WHERE PostID = @PostID------returns a seperate table

    --GET STORY AT GLANCE DATA                                  
    SELECT 
        StoryImage, StoryContent, ALT 
    FROM 
        PostRelatedData 
    WHERE
        PostID = @PostID------returns a seperate table

    --GET POST REFERENCES                                  
    SELECT ReferenceData 
    FROM PostReferences  
    WHERE PostID = @PostID------returns a seperate table
END 

从上面的存储过程中,每个select 语句都会返回一个表.. 我不想也想消除它

优化的存储过程:

CREATE PROCEDURE [dbo].[Optimized_GetArticlePost]            
    (@PostID int)
--[Optimized_GetArticlePost] 715049
AS                                  
BEGIN 
    ------------------------------------------------------------
    ----Declare variable table...
    DECLARE @Temp TABLE (FileName nvarchar(MAX),
                         ImageURL VARCHAR(MAX),
                         StoryImage nvarchar(MAX),
                         StoryContent nvarchar(MAX),
                         ALT nvarchar(MAX),
                         ReferenceData nvarchar(MAX) )  

    SET NOCOUNT ON;                                  

    -- LIST ALL ATTACHMENTS
    INSERT INTO @Temp (FileName)
        SELECT [FileName] 
        FROM CS_PostAttachments                  
        WHERE contenttype LIKE 'audio/mpeg' 
          AND FILENAME LIKE '%.mp3' 
          AND isremote = 1 
          AND postid = @Postid

    --GET THE FB FEED IMAGES FOR THIS POST   
    INSERT INTO @Temp (ImageURL) 
        SELECT ImageURL 
        FROM PostFBImageURL 
        WHERE PostID = @PostID

    --GET STORY AT GLANCE DATA    
    INSERT INTO @Temp (StoryImage,StoryContent,ALT) 
        SELECT StoryImage, StoryContent, ALT 
        FROM PostRelatedData 
        WHERE PostID = @PostID

    --GET POST REFERENCES  
    INSERT INTO @Temp (ReferenceData) 
        SELECT ReferenceData 
        FROM PostReferences  
        WHERE PostID = @PostID

    SELECT * FROM @postDate                             
END 

在上述优化的存储过程中,我将数据插入到一个表变量中,并在最后一次从该临时表中进行选择..

所以,我的问题是:这是否是优化存储过程的正确方法..或者想要在这种情况下如何优化的建议。

提前致谢

【问题讨论】:

  • 最好使用UNION ALL,而不是插入到表变量中。
  • 您尚未将数据插入临时表,您已将数据插入到表变量中。在处理多行时,临时表比表变量要好。
  • 这部分你的 WHERE 子句似乎不正确: contenttype LIKE 'audio/mpeg' 。您在音频/mpeg 之前是否缺少“%”?
  • @Igor 你能用代码说明一下吗...
  • @t-clausen.dk 你的意思是说我应该使用临时表而不是使用表变量...对吗?

标签: sql sql-server stored-procedures optimization


【解决方案1】:

首先:为什么你的临时表有 ALL (n)varchar(max)??不要只是在任何地方都使用(N)VARCHAR(MAX),因为您懒得去想(n)varchar 列的长度应该是多长、合理!了解您的数据 - 使用最合适的数据类型!如果您真的必须有超过 8000 个字符 - 那应该是例外,而不是规则!

另外:要么使用varchar 要么使用nvarchar - 我会尽量避免混合这两者 - 你需要 Unicode - 然后使用nvarchar - 或者你不需要它 - 然后使用varchar

我认为这太可怕了 - 现在每个 @PostID 最多可以有 4 行 - 这真的是你想要的吗?

FileName    ImageUrl    StoryImage    StoryContent   ALT   ReferenceData
------------------------------------------------------------------------
TheFile     NULL        NULL          NULL           NULL  NULL
NULL        SomeUrl     NULL          NULL           NULL  NULL
NULL        NULL        SomeImage     Content        ALT   NULL
NULL        NULL        NULL          NULL           NULL  ReferenceData

似乎是个非常糟糕的主意。

最有可能想要的是跨这些表的 JOIN - 这样您就可以为每个 @PostID 获得 ONE ROW: p>

CREATE PROCEDURE [dbo].[GetArticlePostWithJoins]
    (@PostID int)
AS                                  
BEGIN 
    SELECT 
        pa.[FileName],
        fb.ImageURL,
        rd.StoryImage, rd.StoryContent, rd.ALT,
        pr.ReferenceData 
    FROM 
        CS_PostAttachments pa
    LEFT OUTER JOIN
        PostFBImageURL fb ON fb.PostID = pa.PostID
    LEFT OUTER JOIN
        PostRelatedData rd ON rd.PostID = pa.PostID
    LEFT OUTER JOIN
        PostReferences pr ON pr.PostID = pa.PostID
    WHERE 
        pa.contenttype LIKE 'audio/mpeg' 
        AND pa.FILENAME LIKE '%.mp3' 
        AND pa.isremote = 1 
        AND pa.postid = @Postid ------returns a seperate table
END

【讨论】:

  • 我有一个问题,如果假设需要使用table variabletemp table,,应该使用哪个,为什么?
  • 在一种情况下它不起作用,当在CS_PostAttachments 表中找不到数据时,所有将返回NULL,因为查询依赖于该表
  • @PranavBilurkar:是的,显然 - 我不知道这四个表中的哪一个是始终有数据的 driving 表 - 你可能需要调整它。我只是试图展示我认为正确和最好的方法
  • 不,不是——你必须从一张桌子开始,然后将其他桌子加入其中......
  • @PranavBilurkar:我的回答一个例子......我还能告诉你什么?你必须选择一个表作为起点——你总是有数据的地方——然后加入其他表....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多