C#ADO.net查询运行缓慢

时间:2014-05-23 14:42:21

标签: c# ado.net sql-server-2012

我有一个查询,即.net通过ADO构建并执行到Sql Server 2012.如果ADO执行查询,它会超时等待数据库返回但如果我复制并将其复制到SQL Management工作室并执行它它在不到一秒的时间内返回相同的数据库。

我发现将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();
}

1 个答案:

答案 0 :(得分:0)

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

选项重新编译

....
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))