Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 慢速存储过程_Sql_Sql Server_Networking_Stored Procedures - Fatal编程技术网

Sql 慢速存储过程

Sql 慢速存储过程,sql,sql-server,networking,stored-procedures,Sql,Sql Server,Networking,Stored Procedures,我目前有一个存储过程,可以将内容从一个表复制到另一个表 然而,当它试图只插入27行新行时,它会持续超过12分钟(在这之后,我停止了它),它说影响了27行4次,但是没有进行更改 您能找出以下SP运行缓慢的任何原因吗 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER Procedure [dbo].[sp_CopyCompanyContent] ( @intCopyFromCompanyID Int, @in

我目前有一个存储过程,可以将内容从一个表复制到另一个表

然而,当它试图只插入27行新行时,它会持续超过12分钟(在这之后,我停止了它),它说影响了27行4次,但是没有进行更改

您能找出以下SP运行缓慢的任何原因吗

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[sp_CopyCompanyContent]
(
        @intCopyFromCompanyID Int,
        @intNewCompanyID Int
)
As
Begin
    /*
        RaisError If any of Odl/New Company ID's are 0
    */

    If (@intCopyFromCompanyID = 0 Or @intNewCompanyID = 0)
        Begin
            RaisError('New Company ID or Old Company ID can not be 0', 16, 1)
            Return
        End


    /*
        Create Temp Table For the Content Sections
    */

    If Object_ID('tempdb..#ContentSections') IS Not Null
        Begin 
            Drop Table dbo.#ContentSections
        End 

    /*
        Have to get all the existing data for the Old company we are copying from.
        Have to also add the Max(ContentSectionID) From ContentSection. Max(ContentSectionID) + 
        The Identity (Added further down due to laziness) will be our seed for the ContentID
    */

    Select      CS.ContentID,
                CS.SectionID,
                CS.MenuOrder,
                @intNewCompanyID NewCompanyID,
                CS.CompanyID OldCompanyID,
                CS.SubMenu,
                CS.Link,
                CS.HeaderMenu,
                CS.ParentContentID,
                CRS.*

    Into        dbo.#ContentSections

    From        dbo.Company COMP
    Join        dbo.ContentSection CS
    On          COMP.Company_id = CS.CompanyID  
    Join        dbo.Content CONT
    On          CONT.ContentID = CS.ContentID

    Cross Join  (
                    Select  MAx(ContentSectionID) MaxContentSectionID
                    From    dbo.ContentSection CONT
                ) crs

    Where       COMP.Company_id  = @intCopyFromCompanyID
    Order By    COMP.Company_id


    /*
        We now need to create a table for the existing content for the old company.
        Also have to create the seed. Same principle as above.
    */


    If Object_ID('tempdb..#Content') IS Not Null
        Begin 
            Drop Table dbo.#Content
        End 

    Select  CONT.*, 
            CRS.*

    Into    dbo.#Content

    From    dbo.Company COMP
    Join    dbo.ContentSection CS
    On      COMP.Company_id = CS.CompanyID  
    Join    dbo.Content CONT
    On      CONT.ContentID = CS.ContentID

    Cross Join  (
                    Select  MAx(ContentID) MaxContentID
                    From    dbo.Content CONT
                ) crs

    Where   COMP.Company_id  = @intCopyFromCompanyID
    Order By COMP.Company_id

    /*  
        Add Identity to each of the tables we have created above. The ID fields will add to 
        the Max of each table to mimic what the future seeds will be.
    */

exec('Alter table #ContentSections Add ID Int Identity(1,1)')
exec('Alter table #Content Add ID Int Identity(1,1)')

    /*
        Add content data from the temp table.
    */


    Insert  Into dbo.Content
    (
            Title,
            Content
    )   
    Select  Title,
            Content 
    From    dbo.#Content

    /*
        Have to the Content table up to the content sections table
        as this contains what ID has been add to the Content Table. 
    */


    Insert Into dbo.ContentSection
    (
            ContentID,
            SectionID,
            MenuOrder,
            CompanyID,
            SubMenu,
            Link,
            HeaderMenu,
            ParentContentID
    )

    Select  C.MaxContentID + C.ID,
            CS.SectionID,
            CS.MenuOrder,
            CS.NewCompanyID,
            CS.Submenu,
            CS.Link,
            CS.HEaderMEnu,
            CS.ParentContentID
    From    dbo.#Content C
    Join    dbo.#ContentSections CS
    On      C.ID = CS.ID

End

这可能是因为标识(它是4倍*27行的2倍)

相反,如果您不想创建表,请尝试使用
ROW\u NUMBER()OVER()…
子句作为ID,这样以后就不需要创建标识了

如我所见,您甚至不需要使用临时表,因为这样您就可以简单地使用两个select as
INSERT INTO。。。。用
行号()选择…


似乎您没有对
临时表进行任何更改,因此您可能不需要它们。(仅当您想在SP的范围之外使用它们时)

首先要检查选择的查询计划,因为交叉连接是危险的,如果我没有读错,您会在CRS中显示相同的值。*在每个记录中,对吗? 如果是这样,请在select之前进行查询,并将结果存储在变量中,并在select中显示,类似这样

DECLATE @maxValue INTEGER
Select  @maxValue=MAX(ContentID) MaxContentID
                    From    dbo.Content CONT
Select  CONT.*, 
            @maxValue as MaxContentID

    Into    dbo.#Content

    From    dbo.Company COMP
    Join    dbo.ContentSection CS
    On      COMP.Company_id = CS.CompanyID  
    Join    dbo.Content CONT
    On      CONT.ContentID = CS.ContentID
    Where   COMP.Company_id  = @intCopyFromCompanyID
    Order By COMP.Company_id

您是否使用查询分析器来显示执行计划?一个很好的起点是在打开SET STATISTICS IO的情况下运行存储的过程并获取执行计划。可能会让你更好地理解问题所在?@RyanMcDonough-你的语句更有可能被另一个语句阻塞。你不应该需要order by子句或交叉连接。您可以将交叉联接的结果存储在变量中,并在需要时使用下游的值。@RyanMcDonough-不,这是我的观点。您更改了某些内容,并认为性能提高是由于该更改,但除非您是该服务器上唯一连接的用户,您的第一条语句很可能被其他人阻止,例如从应用程序中提取一个大报告,而您的第二条语句没有。我使用临时表,以便可以为它们提供所有新的0-27 ID,然后在插入新表时,我将临时ID添加到现有ID中,这样就不会过度写入旧的行。不过我会调查你的想法。
DECLATE @maxValue INTEGER
Select  @maxValue=MAX(ContentID) MaxContentID
                    From    dbo.Content CONT
Select  CONT.*, 
            @maxValue as MaxContentID

    Into    dbo.#Content

    From    dbo.Company COMP
    Join    dbo.ContentSection CS
    On      COMP.Company_id = CS.CompanyID  
    Join    dbo.Content CONT
    On      CONT.ContentID = CS.ContentID
    Where   COMP.Company_id  = @intCopyFromCompanyID
    Order By COMP.Company_id