0

我正在运行一个 C# 应用程序,它根据输入重复查询 SQL Server 10.50.1617 上的数据库。SQL 查询是应用程序中的嵌入式资源。在过去,它工作得很好。最近我们收到了更频繁的 SQL“超时过期”错误,现在是程序永远无法完成的地步。我尝试改变程序连接数据库的逻辑,使查询更小但数量更多。这没有任何效果。

此外,从调试中我看到超时是随机发生的。例如,有时它甚至无法完成 1 个查询(直接在 SSMS 中完成的查询不到 1 秒)。其他时候,它会在第 900 个查询时超时。

我对这个主题做了一些研究,发现其他人也有类似的问题(例如,这篇文章:SQL timeout expired on fast query

似乎提供了一些有用的建议,关于处理事务等。但是,我认为我在集成 C#(我通过 Visual Studio 使用)和数据库等主题方面的背景要弱得多。所以我发现这些问题的答案很难理解。更糟糕的是,我试图在其他人的代码中解决这个问题,而我最初并没有编写。

鉴于我收到此错误,我希望有人可以对我可能想要研究的一些事情提供更多外行的解释。我对此真的很陌生,虽然我确实了解大部分术语,但我仍然对所有活动部件感到头疼。

我可能想要查看或考虑修改我的代码的哪些方面?这可能是我的 C# 代码的问题,还是数据库可能存在问题(由于最初编写了此应用程序,数据库已经变得非常大,并且继续这样做)?任何建议表示赞赏,请让我知道我可以提供的任何其他信息。

protected IEnumerable<IDictionary<string, object>> ExecuteQuery(
            string query,
            IDictionary<string, object> parameters,
            IEqualityComparer<string> comparer = null)
        {

            using (DbCommand command = GetCommand())
            {
                command.CommandText = query;
                if (parameters != null)
                {
                    foreach (var pair in parameters)
                    {
                        DbParameter parameter = command.CreateParameter();
                        parameter.ParameterName = string.IsNullOrEmpty(ParameterPrefix)
                            ? pair.Key
                            : ParameterPrefix + pair.Key;
                        parameter.Value = pair.Value == null ? DBNull.Value : pair.Value;
                        command.Parameters.Add(parameter);
                    }
                }
                using (DbDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var dict = comparer == null
                            ? new Dictionary<string, object>(reader.FieldCount)
                            : new Dictionary<string, object>(reader.FieldCount, comparer);
                        for (int i = 0; i < reader.FieldCount; ++i)
                        {
                            dict[reader.GetName(i)] = reader[i] == DBNull.Value ? null : reader[i];
                        }
                        yield return dict;
                    }
                }
            }
        }

代码通常由许多不同的 .cs 文件组成,因此我不确定发布哪个部分最有效率,但这里是在其他地方调用的函数,用于执行查询。我认为这可能是最相关的起点。

使用“使用”语法调用数据库命令,理论上应该处理处置问题,我想......

4

1 回答 1

0

对于超时的查询,基本上有两种解决方案。

首先,您必须确保设置了超时,以便只有在确实出现问题时才会触发它,严重的错误以至于您想放弃查询而不是稍等片刻。因此,例如,如果查询通常需要 5 秒,您可能希望超时接近 30 秒。如果它们通常需要 30 秒,您可能需要 2 分钟或更长时间的超时。

其次,您必须确保查询在尽可能短的时间内完成。

这不是一个通用的答案,但是对于如何使查询运行得更快有很多建议。如果这是一个相对较新的应用程序,则可能很少考虑例如适当的索引。但是,每个查询的最佳方法可能不同。

于 2013-09-26T15:43:08.540 回答