Eri*_*gum 11 performance sql-server ado.net execution-plan configuration
所以我确定我的 SQL Server 的不稳定行为是因为 .Net SqlClient 数据提供程序的默认设置SET ARITHABORT OFF
. 话虽如此,我已经阅读了各种文章,这些文章讨论了实现这一点的最佳方式。对我来说,我只是想要一个简单的方法,因为 SQL Server 正在遭受痛苦,而且我的查询调优还没有完全超越整个应用程序(显然SET
在 sp 中添加是行不通的)。
在 Erland Sommarskog关于该主题的精彩文章中,他基本上建议采取安全的方法,通过更改应用程序来发出SET ARITHABORT ON
连接。但是,在 dba.stackexchange question 的这个答案中,Solomon Rutzky提供了实例范围和数据库范围的方法。
设置此实例范围内我在这里遗漏了什么后果?正如我所看到的......因为SSMSON
默认设置了这个,我认为ON
为所有连接设置这个服务器范围没有坏处。归根结底,我只需要这个 SQL Server 来执行高于一切。
Sol*_*zky 11
有些默认值的存在仅仅是因为没有人真正知道更改它们会产生什么效果。例如,在使用“美国英语”作为操作系统语言的系统上安装时的默认实例级排序规则是SQL_Latin1_General_CP1_CI_AS
. 这是没有意义的,因为SQL_*
排序规则是为了 SQL Server 2000 之前的兼容性。从 SQL Server 2000 开始,您实际上可以选择 Windows 排序规则,因此美国英语系统的默认设置应该已更改为Latin1_General_CI_AS
. 但是,我想微软没有人真正知道这会对所有各种潜在的子系统和系统存储过程等产生什么影响。
因此,我不知道将其设置为 ON 作为数据库默认值甚至实例范围的任何特定负面影响。同时,我没有测试过。但即使我已经对其进行了测试,我可能仍然不会使用与您的应用程序相同的代码路径,因此这确实是您需要在您的环境中进行测试的内容。将其设置为ON
在您的开发和 QA 环境中的实例级别,看看它是如何工作的一两个月。然后在 Staging / UAT 中启用它。如果几周内一切顺利,请将该配置更改滚动到生产环境。关键是要留出尽可能多的时间来测试每天未命中的各种代码路径。有些每周或每月或每年都会受到打击。某些代码路径仅受到支持,或某些人多年前创建的临时报告或维护过程的影响,但从未告诉过您并且仅在随机时间间隔内使用(不,从未发生过;-)。
因此,我对一个仍然具有默认“用户选项”设置的实例进行了一些测试,因为我从未更改过它。
请注意:
@@OPTIONS
/'user options'
是位掩码值ARITHABORT ON
我使用 SQLCMD(使用 ODBC)和 LINQPad(使用 .NET SqlClient)进行了测试:
SQLCMD -W -S (local) ^
-Q"SELECT CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')') FROM sys.dm_exec_sessions ses WHERE ses.[session_id] = @@SPID;"
echo .
Run Code Online (Sandbox Code Playgroud)
(the^
是 DOS 行的续行符;.
最后一行的只是强制多出一行以便于复制和粘贴)
在 LINQPad 中:
SQLCMD -W -S (local) ^
-Q"SELECT CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')') FROM sys.dm_exec_sessions ses WHERE ses.[session_id] = @@SPID;"
echo .
Run Code Online (Sandbox Code Playgroud)
SQLCMD 返回:
using (SqlConnection connection =
new SqlConnection(@"Server=(local);Trusted_Connection=true;Database=tempdb;"))
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = @"SELECT @RetVal =
CONCAT(DB_NAME(), N': ', @@OPTIONS & 64, N' (', ses.[client_interface_name], N')')
FROM sys.dm_exec_sessions ses
WHERE ses.[session_id] = @@SPID;";
SqlParameter paramRetVal = new SqlParameter("@RetVal", SqlDbType.NVarChar, 500);
paramRetVal.Direction = ParameterDirection.Output;
command.Parameters.Add(paramRetVal);
connection.Open();
command.ExecuteNonQuery();
Console.WriteLine(paramRetVal.Value.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
LINQPad 返回:
master: 0 (ODBC)
Run Code Online (Sandbox Code Playgroud)
以下 T-SQL 启用时ARITHABORT
无需删除可能设置的任何其他选项,并且如果位ARITHABORT
掩码值中已设置,则无需更改任何内容。
DECLARE @UserOptions INT;
-- Get current bitmasked value and ensure ARITHABORT is enabled:
SELECT @UserOptions = CONVERT(INT, cnf.[value_in_use]) | 64 -- enable "ARITHABORT"
FROM sys.configurations cnf
WHERE cnf.[configuration_id] = 1534 -- user options
-- Apply new default connection options:
EXEC sys.sp_configure N'user options', @UserOptions;
RECONFIGURE;
Run Code Online (Sandbox Code Playgroud)
SQLCMD 返回:
tempdb: 0 (.Net SqlClient Data Provider)
Run Code Online (Sandbox Code Playgroud)
LINQPad 返回:
DECLARE @UserOptions INT;
-- Get current bitmasked value and ensure ARITHABORT is enabled:
SELECT @UserOptions = CONVERT(INT, cnf.[value_in_use]) | 64 -- enable "ARITHABORT"
FROM sys.configurations cnf
WHERE cnf.[configuration_id] = 1534 -- user options
-- Apply new default connection options:
EXEC sys.sp_configure N'user options', @UserOptions;
RECONFIGURE;
Run Code Online (Sandbox Code Playgroud)
鉴于:
ARITHABORT OFF
ARITHABORT ON
OFF
ARITHABORT
,因此它们接受默认设置我建议更改实例范围的默认连接选项(如上所示)。这将比更新应用程序更不突兀。如果您发现更改实例范围的设置有问题,我只会更新应用程序。
PS 我做了一个简单的测试,改变tempdb
而不是改变实例范围的设置,但它似乎不起作用。
归档时间: |
|
查看次数: |
1301 次 |
最近记录: |