我们正在使用C#和Linq2SQL从数据库中获取某些报告的数据。在某些情况下,这需要一段时间。超过30秒,这似乎是默认的CommandTimeout
。
所以,我想我必须提升CommandTimeout
。但问题是,多少钱?将它设置得很高是不是很糟糕?如果客户试图做某事并且因为他的数据库中的数据比普通客户更多,他因为超时而无法获得报告,那会不是很糟糕?但我怎么知道它可能需要多长时间?有没有办法将它设置为无限?或者这被认为是非常糟糕的?
我应该在哪里设置它?我有一个静态数据库类,它在我需要时为我生成一个新的datacontext。我可以创建一个常量并在创建新的datacontext时设置它吗?或者它应根据用例设置为不同的值?对于那些不会花费太多时间的事情,有一个高超时是不是很糟糕?或者这不重要吗?
太高ConnectionTimeout
当然会更烦人。但是,是否存在用户/客户希望超时的情况? SQL服务器是否可以冻结,以便命令永远不会完成?
答案 0 :(得分:4)
CommandTimeout
等。这可以避免意外长时间阻塞等情况(或者更糟:未检测到的死锁情况)。至于如何高...查询需要多长时间?添加一些空间,你有答案。
当然,要做的另一件事是减少查询所花费的时间。这可能意味着手动优化sproc中的某些TSQL,通常与检查索引策略相结合,也可能是更大的更改,例如非规范化或其他模式更改。这可能还涉及数据仓库策略,因此您可以将负载转移到单独的数据库(远离事务数据),并为报告优化模式。也许是一个明星模式。
我不会把它设置为无限......我不希望它能够永远地运行报告。选择一个对报告有意义的数字。
是的,SQL Server可以冻结,以便命令永远不会完成。一个开放的阻塞事务将是最简单的...得到两个,你可以死锁。通常系统会检测到本地死锁 - 但并非总是如此,尤其是涉及DTC时(即非本地锁定)。
答案 1 :(得分:0)
恕我直言,用户设置ConnectionTimeout值的高级选项将优于您确定的任何常量值。
答案 2 :(得分:0)
默认情况下,主键将在其上具有聚簇索引。我发现以下脚本(我认为它是在msdn上)将生成代码以创建SQL服务器认为有用的任何索引(def适用于SQL2008,我认为这是在2005年引入的):
SELECT
migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle)
+ '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'
+ ' ON ' + mid.statement
+ ' (' + ISNULL (mid.equality_columns,'')
+ CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END
+ ISNULL (mid.inequality_columns, '')
+ ')'
+ ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,
migs.*, mid.database_id, mid.[object_id]
FROM sys.dm_db_missing_index_groups mig
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10
ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC
答案 3 :(得分:0)
//If you have an AseCommand object instance....
AseCommand _AseCommand = new AseCommand("procedure_test");
//You can set up the timeout infinite as follows
_AseCommand.CommandTimeout = System.Threading.Timeout.Infinite;