更新:看起来查询不会抛出任何超时。连接超时。
这是用于执行查询的示例代码。有时,在执行耗时的查询时,会抛出超时异常。
我无法使用以下任何技术: 1)增加超时。 2)使用回调异步运行它。这需要以同步方式运行。
请执行任何其他技术以在执行耗时的查询时保持连接活动?
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
答案 0 :(得分:16)
由于您使用的ExecuteNonQuery不返回任何行,因此您可以尝试这种基于轮询的方法。它以asyc方式执行查询(没有回调) 但应用程序将等待(在while循环内),直到查询完成。来自MSDN。这应该解决超时问题。请试一试。
但是,我同意其他人的看法,你应该多考虑优化查询,以便在30秒内完成。
IAsyncResult result = command.BeginExecuteNonQuery();
int count = 0;
while (!result.IsCompleted)
{
Console.WriteLine("Waiting ({0})", count++);
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Command complete. Affected {0} rows.",
command.EndExecuteNonQuery(result));
答案 1 :(得分:4)
您应首先检查您的查询,看它是否已经过优化,并且不会以某种方式运行缺失的索引。 30秒为大多数查询分配,即使在大型数据库上进行了适当调整也是如此。如果您有使用查询计划的可靠证据,查询无法以更快的速度执行,那么您应该增加超时,没有其他方法来保持连接,这是超时终止连接的目的,如果查询未在该时间范围内完成。
答案 2 :(得分:1)
我必须同意Terrapin。
您可以选择如何缩短时间。首先,如果您的公司雇佣了DBA,我建议您向他们寻求建议。
如果这不是一个选项,或者如果你想先尝试一些其他的东西,这里有三个主要选择:
答案 3 :(得分:1)
如果您受限于使用更改超时值的默认过程,您很可能需要做更多的工作。想到以下选项
答案 4 :(得分:1)
我们最近在SQL Server 2000数据库上遇到了类似的问题。
在查询期间,在数据库服务器上的主数据库上运行此查询,并查看是否存在应该进行故障排除的锁定:
select
spid,
db_name(sp.dbid) as DBname,
blocked as BlockedBy,
waittime as WaitInMs,
lastwaittype,
waitresource,
cpu,
physical_io,
memusage,
loginame,
login_time,
last_batch,
hostname,
sql_handle
from sysprocesses sp
where (waittype > 0 and spid > 49) or spid in (select blocked from sysprocesses where blocked > 0)
SQL Server Management Studio 2008还包含一个非常酷的活动监视器,可让您在查询期间查看数据库的运行状况。
在我们的例子中,它是一个使网络繁忙的网络锁。这是一些遗留的VB代码,它没有足够快地断开其结果集。
答案 5 :(得分:1)
如果禁止使用数据访问API的功能来允许查询持续超过30秒,那么我们需要查看SQL。
与优化SQL的优势相比,优化ADO.NET使用所带来的性能提升很小。
您已经在使用最有效的SQL执行方法。其他技术会慢慢变慢(尽管如果你快速检索你的行并且使用DataSet的一些非常慢的客户端处理,你可能能够将初始检索缩短到不到30秒,但我对此表示怀疑。 )
如果我们知道您是否正在插入,那么也许您应该使用批量插入。但是我们不知道你的sql的内容。
答案 6 :(得分:1)
这是一个UGLY hack,但可能有助于临时解决您的问题,直到您可以解决实际问题
private static void CreateCommand(string queryString,string connectionString)
{
int maxRetries = 3;
int retries = 0;
while(true)
{
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
break;
}
catch (SqlException se)
{
if (se.Message.IndexOf("Timeout", StringComparison.InvariantCultureIgnoreCase) == -1)
throw; //not a timeout
if (retries >= maxRetries)
throw new Exception( String.Format("Timedout {0} Times", retries),se);
//or break to throw no error
retries++;
}
}
}
答案 7 :(得分:0)
command.CommandTimeout *= 2;
这将使默认超时时间加倍,即30秒。
或者,将CommandTimeout的值放在配置文件中,这样您就可以根据需要进行调整而无需重新编译。
答案 8 :(得分:0)
如果你绝对无法增加超时,你唯一的选择就是减少查询在默认的30秒超时内执行的时间。
答案 9 :(得分:0)
您应该将查询分成多个块,每个块在超时期限内执行。
答案 10 :(得分:0)
我倾向于不喜欢增加连接/命令超时,因为在我看来这是一个处理症状的问题,而不是问题
答案 11 :(得分:0)
只需将sqlcommand的CommandTimeout属性设置为0,这将导致命令等待查询完成... 例如:
SqlCommand cmd = new SqlCommand(spName,conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
答案 12 :(得分:0)
您是否考虑过将查询分解为几个较小的块?
此外,您是否在数据库引擎优化顾问中运行了查询:
Management Studio>工具>数据库引擎优化顾问
最后,我们可以看一下查询本身吗?
欢呼声
答案 13 :(得分:0)
您是否尝试将sql包装在存储过程中,它们似乎有更好的内存管理。在使用经典ADO进行内部查询的plan sql语句之前,已经看到过这样的超时。即select * from(select ....)t inner join somthingTable。内部查询返回大量结果的位置。
其他提示 1.使用with(nolock)执行提示执行读取,它很脏,我不推荐它,但它会更快。 2.还要查看您尝试运行的sql的执行计划,并减少行扫描,即连接表的顺序。 3.查看为表添加一些索引以便更快地读取。 4.我还发现删除行非常昂贵,您可以尝试限制每次调用的行数。 5.使用#temporary表交换@table变量在过去对我也有用。 6.您可能还保存了糟糕的执行计划(听到,从未见过)。
希望这有帮助
答案 14 :(得分:0)
更新:看起来查询没有 抛出任何超时。连接是 超时。
I.o.w。,即使您不执行查询,连接也会超时?因为有两个超时:连接和查询。每个人似乎都专注于查询,但是如果你得到连接超时,那就是网络问题并且与查询无关:显然,必须首先建立连接,然后才能运行查询。
答案 15 :(得分:0)
尝试将结果分页回来可能是值得的。