Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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
仅.net SqlDataAdapter中的简单查询超时_.net_Sql_Sqldataadapter - Fatal编程技术网

仅.net SqlDataAdapter中的简单查询超时

仅.net SqlDataAdapter中的简单查询超时,.net,sql,sqldataadapter,.net,Sql,Sqldataadapter,好的,我有一个查询,在Sql Management Studio中运行需要2-5秒。但当我通过.net应用程序运行它时,每次都超过了CommandTimeout的5分钟 我知道.net代码是有效的,因为这段代码(如下)可以很好地执行其他查询,并提供结果 public DataTable ExecuteQuery() { DataTable result = new DataTable(); FoSqlConn con = new FoSqlConn(Con

好的,我有一个查询,在Sql Management Studio中运行需要2-5秒。但当我通过.net应用程序运行它时,每次都超过了CommandTimeout的5分钟

我知道.net代码是有效的,因为这段代码(如下)可以很好地执行其他查询,并提供结果

public DataTable ExecuteQuery()
    {
        DataTable result = new DataTable();
        FoSqlConn con = new FoSqlConn(ConnectionToUse, ApplicationName); // connection string factory
        List<string> parameterNames = GetAllParametersFromQueryString(QueryString);
        using (SqlConnection sqlCon = new SqlConnection(con.GetConnectionString()))
        {
            using (SqlCommand cmd = new SqlCommand(QueryString, sqlCon))
            {
                if (DefaultTimeout.HasValue == true)
                {
                    cmd.CommandTimeout = DefaultTimeout.Value;
                }
                foreach (string paramName in parameterNames)
                {
                    if (Context.ParameterExists(paramName))
                    {
                        cmd.Parameters.AddWithValue(paramName, Context.GetParameterByName(paramName));
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue(paramName, DBNull.Value);
                    }
                }
                sqlCon.Open();
                using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
                {
                    adapter.Fill(result);
                }
                if (sqlCon.State == ConnectionState.Open)
                {
                    con.CloseConnection();
                }
            }
        }

        return result;
    }
运行这个精确的查询,我得到了相同的结果(它实际上完成了,通过这个方法运行它只需要5分钟以上,而不是直接运行查询需要3秒钟)注意我也尝试使用指定为nvarchar(4000)的参数运行查询,但仅在Sql management studio中运行查询就可以了

UPDATE#3我已经更新了查询中连接的所有表的统计信息,没有运气。sp_executeSQL查询仍然需要将近5分钟的时间(比重建统计数据之前大约少30秒)。在这一点上,我不知所措。有什么想法吗


更新#4终于找到了解决方案!这个问题是由于我在生成结果查询之前使用了if条件的“参数嗅探”。执行计划引擎假设参数作为null传递时,将作为null命中查询,但事实并非如此。它们总是有价值的。为了纠正这个问题,我在查询开始时删除了if条件,并在使用参数的地方放置了ISNULL检查。这将通知执行计划我的意图,sp_executeSQL调用的执行速度与Sql Management Studio的执行速度相同。谢谢大家的帮助

尝试使用SQL探查器进行测试

检查sql命令是否在您认为是并且没有被延迟的情况下发送到数据库


另外,检查数据库接收到的查询的实际文本,然后在ManagementStudio中运行该文本。数据库可能接收到的内容与您期望的不完全一致。

这几乎肯定是一个缓存不正确的查询计划(这是典型症状)。这通常是过时统计数据的结果

我建议你

检查统计数据是否“扭曲”或过时的一种方法是在实际执行计划打开的情况下运行查询,然后检查每个运算符中的估计行与实际行


更新(回应评论):您可以尝试重建所有索引。作为最后一种手段,您可以尝试使用
将存储过程标记为重新编译
,这基本上就是在运行SQLServerManagementStudio(SSMS)时发生的情况。这将最终确定它是否是不适当的缓存查询计划。如果是,则可以使用
优化

标记存储的过程,以便探查器发现我的Sql Management Studio正在运行,而不是.net执行的查询。我只是使用带有readuncommitted行的TextData过滤器进行过滤,因为这是唯一使用该语句的查询。最有趣的是,ConnectionString一旦在SqlConnection对象中,就会丢失密码,但它在给定的字符串构造函数变量中。非常奇怪的是,统计数据可能已经过时,但也有可能您得到了两个不同的执行计划。尝试在Sql Management Studio中运行原始查询和sp_executesql版本,并比较执行计划()。它们是一样的吗?谢谢,我比较过了,它们是不同的。我刚刚刷新了执行计划,sp_executeSQL调用仍然会产生非常慢的结果。但需要注意的是,我在联接中使用了一个视图。我也更新了视图表上的统计数据……这里有一篇关于执行计划提示的好文章:看看你是否能让两个执行计划匹配。嘿,我几分钟前才找到那篇文章!我认为你的答案是正确的,但现在我仍然不明白为什么直接运行查询会生成一个完全不同的、更有效的执行计划,而不是通过sp_ExecuteSQL执行相同的sql。我将就此提出一个问题。我发现.net代码与从Sql Management Studio运行的查询之间的区别在于通过sp_executesql过程执行。(通过这个过程运行查询需要5分钟,而SQLManagementStudio直接运行不到3秒)好的,所以我更新了统计数据,它应该已经清除了执行计划,但事实上,它仍然生成了同样糟糕的执行计划。我不知道还能做什么。。。编辑我更新了查询涉及的每个表的统计信息。问题是由于我的If条件造成的。参数嗅探在构建执行计划时假设my@StartDate和@EndDate为null,而事实上,它们永远不会作为null传递。我交换了if条件,并在使用参数的地方使用了ISNULL方法,它工作起来很有魅力!
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF (@StartDate IS NULL)
BEGIN 
    SET @StartDate = DATEADD(Day, -60, GETDATE())
END 

IF (@EndDate IS NULL)
BEGIN
    SET @EndDate = DATEADD(DAY, -1, GETDATE())
END

SELECT
    P.ProductionObjDimId
    ,Dim.ProductionObjSourceId
    ,Dim.Name as WellName
    ,Dim.CurrentStatus
    ,Dim.ApiCode
    ,Dim.CurrentType
    ,Dim.StateProvidenceCode
FROM 
    ProductionDetail as P with(nolock)

JOIN DataWarehouse.dbo.ProductionObjMetaData as M
ON  P.ProductionObjDimId = M.ProductionObjDimId
AND M.OperationType = 1

JOIN DataWarehouse.dbo.ProductionObjDim as Dim
ON P.ProductionObjDimId = Dim.ProductionObjDimId

LEFT OUTER JOIN ProductionForecastingLinksView as Forcast
ON  Dim.ProductionObjSourceId = Forcast.comp_sk
AND Forcast.StartDate <= @EndDate
AND Forcast.EndDate > @StartDate

LEFT OUTER JOIN DataWarehouse.dbo.ForecastingUpload as Upload
ON Forcast.propnum = Upload.ForecastingWellSourceId
AND Upload.StartDate <= @EndDate
AND Upload.EndDate > @StartDate
AND (Upload.UploadDaily = 1 OR Upload.UploadMonthly = 1)
WHERE 
    P.ProductionDate >= @StartDate
AND
    Upload.ForecastingWellSourceId IS NULL
GROUP BY
    P.ProductionObjDimId
    ,Forcast.propnum        
    ,Dim.ProductionObjSourceId
    ,Dim.Name
    ,Dim.CurrentStatus
    ,Dim.ApiCode
    ,Dim.CurrentType
    ,Dim.StateProvidenceCode
Having 
    SUM(P.GrossOilProduction) > 0
OR  SUM(P.GrossGasSale) > 0
order by WellName
exec sp_executesql N'SET TRANSACTION ISOLATION...[SAME CODE AS ABOVE]' ,@StartDate=NULL,@EndDate=NULL