繁体   English   中英

C#ADO.net查询运行缓慢

[英]C# ADO.net query runs slow

我有一个.net通过ADO构建并执行到SQL Server 2012的查询。如果ADO执行查询,它将超时,等待数据库返回,但是如果我将其复制并粘贴到SQL Management Studio中并针对同一数据库执行该查询在不到一秒钟的时间内返回。

我发现将ADO生成的查询包装在'将其存储在SQL变量中并使用SP_EXECUTESQL的情况下,它运行起来既好又快速。 为什么会有区别? 我没有以任何方式更改查询。

这是它构建和执行的查询之一(我省略了动态构建CommandText设置为的字符串的所有代码)。

using(SqlConnection conn = ConnectionStringHelper.GetOpenConnection)
using(SqlCommand cmd = conn.CreateCommand)
{
    cmd.CommandType = CommandType.Text;
    cmd.Parameters.AddWithValue("agencyID", broadcastAgencyID);
    cmd.Parameters.AddWithValue("tableName", mapping.TableName);
    cmd.Parameters.AddWithValue("schemaName", mapping.SchemaName);
    cmd.Parameters.AddWithValue("broadcastEntityMappingID", mapping.BroadcastEntityMappingID);

    cmd.CommandText = @"SET NOCOUNT ON; 
        DECLARE @currentAgencyID NVARCHAR(MAX)
        DECLARE @currentFacilityID NVARCHAR(MAX)

        DECLARE @currentAgencyEntityBroadcastID INT
        SELECT broadcastEntity.AgencyID, broadcastEntity.FacilityID
        INTO #missingBroadcasts
        FROM [Resource].[AgencyFacility] broadcastEntity
        LEFT JOIN(
            SELECT keys.AgencyID, keys.FacilityID
                , record.BroadcastAgencyID
                , record.AgencyEntityBroadcastID
            FROM [Propagation].[AgencyEntityBroadcast] record
            INNER JOIN (
                SELECT AgencyEntityBroadcastID
                    ,[AgencyID], [FacilityID]
                FROM (
                    SELECT AgencyEntityBroadcastID
                        ,ColumnName AS [PropagationColumnName]
                        ,ColumnValue AS [PropagationColumnValue]
                    FROM Propagation.AgencyEntityBroadcastKeys
                    ) Keys
                PIVOT(MAX(PropagationColumnValue) FOR PropagationColumnName IN (
                            [AgencyID], [FacilityID]
                            )) pivoted
                ) keys ON keys.AgencyEntityBroadcastID = record.AgencyEntityBroadcastID
                WHERE record.BroadcastAgencyID = @agencyID
                    AND record.BroadcastEntityMappingID = @broadcastEntityMappingID
            ) keys ON keys.BroadcastAgencyID = broadcastEntity.AgencyID
                AND keys.AgencyID = broadcastEntity.AgencyID
            AND keys.FacilityID = broadcastEntity.FacilityID
        WHERE broadcastEntity.AgencyID = @agencyID
            AND keys.AgencyEntityBroadcastID IS NULL
        DECLARE entity_cursor CURSOR FOR
        SELECT * FROM #missingBroadcasts

        OPEN entity_cursor
        FETCH NEXT FROM entity_cursor
        INTO @currentAgencyID, @currentFacilityID
        WHILE @@FETCH_STATUS = 0
        BEGIN
            INSERT INTO Propagation.AgencyEntityBroadcast(
                BroadcastAgencyID,
                BroadcastEntityMappingID,
                BroadcastTypeID,
                CreatedOn,
                ModifiedOn
            )
            VALUES(
                @agencyID,
                @broadcastEntityMappingID,
                1,
                GETUTCDATE(),
                GETUTCDATE()
            )

            SET @currentAgencyEntityBroadcastID = (SELECT SCOPE_IDENTITY())
            INSERT INTO Propagation.AgencyEntityBroadcastKeys(
                AgencyEntityBroadcastID,
                ColumnName,
                ColumnValue
            ) VALUES (
                @currentAgencyEntityBroadcastID,
                'AgencyID',
                @currentAgencyID
            )
        INSERT INTO Propagation.AgencyEntityBroadcastKeys(
            AgencyEntityBroadcastID,
            ColumnName,
            ColumnValue
        ) VALUES (
            @currentAgencyEntityBroadcastID,
            'FacilityID',
            @currentFacilityID
        )

        FETCH NEXT FROM entity_cursor INTO @currentAgencyID, @currentFacilityID
        END

        CLOSE entity_cursor
        DEALLOCATE entity_cursor

        DROP TABLE #missingBroadcasts

        SET NOCOUNT OFF;";

    cmd.ExecuteNonQuery();
}

这种行为通常是由参数嗅探问题引起的。 您可以尝试使用选项重新编译或针对未知进行优化。

选项重新编译

....
WHERE broadcastEntity.AgencyID = @agencyID
            AND keys.AgencyEntityBroadcastID IS NULL
OPTION (RECOMPILE)

针对未知进行优化

.....
WHERE broadcastEntity.AgencyID = @agencyID
      AND keys.AgencyEntityBroadcastID IS NULL
OPTION (OPTIMIZE FOR (@agencyID UNKNOWN, @broadcastEntityMappingID UNKNOWN))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM