将查询抽象为存储过程会使其运行非常缓慢 [英] Abstracting out a query to a stored procedure makes it run very slowly

查看:31
本文介绍了将查询抽象为存储过程会使其运行非常缓慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很长的存储过程,其中包含许多插入不同表的逻辑块.这是一个这样的块

I have a very long stored procedure with a number of blocks of logic in it that insert to different tables. Here's one such block

我有下表对数据"有唯一的约束

I have the following table with a unique constraint on 'data'

[id] [int] IDENTITY(1,1) NOT NULL
[data] [varchar](512) NULL

此块尝试向数据"插入一个值.如果该值是唯一的,则将其插入.在所有情况下都返回相关数据 id

This block attempts to insert a value to 'data'. if that value is unique, it is inserted. In all cases the relevant data id is returned

BEGIN TRY 
    INSERT INTO Data SELECT @data; 
END TRY 
BEGIN CATCH 
END CATCH   
SET @data_id = (SELECT id FROM Data WHERE data = @data); 

当我在原始存储过程中包含这段代码时,它运行良好.然而,为了整洁,我和 DRY,我想我会把它抽象成一个子过程,因为在其他一些 SP 中调用了相同的块

When I include this block of code in my original stored procedure, it runs fine. However, for the sake of neatness I and DRY, I thought I'd abstract it out to a sub-procedure, as the same block is called in a few other SPs

ALTER PROCEDURE [dbo].[q_Data_TryInsert]

   @data nvarchar(512),
   @id INT OUTPUT

AS
BEGIN

    BEGIN TRY 
        INSERT INTO Data SELECT @data; 
    END TRY 
    BEGIN CATCH 
    END CATCH   
    SET @id = (SELECT id FROM Data WHERE data = @data);     

END

然后我这样称呼这个抽象的 SP

I then call this abstracted SP like so

EXEC [q_Data_TryInsert] @data, @data_id OUTPUT

即使代码相同,抽象的 SP 也会使整个过程减慢几个数量级.

The abstracted SP slows down the whole process my several orders of magnitude, even though the code is the same.

为什么会这样?

推荐答案

INSERT INTO [PKvalue] ([value])
select 'Data6' as [value] 
 where not exists (select top 1 ID from [PKvalue] where [value] = 'Data6');
select top 1 ID from [PKvalue] where [value] = 'Data6';

INSERT INTO data (data)
select @dtata as [data] 
 where not exists (select top 1 ID from [data] where [data] = @data);
select top 1 ID from [data] where [data] = '@data;

甚至不需要交易.该插入是一个事务.即使在选择之前发生了另一个插入,您仍然会得到正确的答案.只有删除或更新才能破坏选择.事务有开销.

Don't even need a transaction. That insert is a transaction. Even if another insert happened before the select you would still get the right answer. Only a delete or update could break the select. A transaction has overhead.

这篇关于将查询抽象为存储过程会使其运行非常缓慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆