Каковы последствия установки ARITHABORT ON для всех соединений в SQL Server?

10

Итак, я решил, что ошибочное поведение моего SQL Server связано с настройкой по умолчанию поставщика данных .Net SqlClient SET ARITHABORT OFF. С учетом сказанного я прочитал различные статьи, в которых обсуждается лучший способ реализации этого. Для меня я просто хочу простой способ, потому что SQL Server страдает, и моя настройка запросов не полностью перешагнула через приложение (и очевидно, что добавление SETв sp НЕ РАБОТАЕТ).

В блестящей статье Эрланда Соммарскога на эту тему он в основном предлагает использовать безопасный подход, изменив приложение для выдачи SET ARITHABORT ONсоединения. Однако в этом ответе на вопрос dba.stackexchange Соломон Рутцки предлагает подход как на уровне экземпляра, так и на уровне базы данных.

Какие последствия я здесь упускаю при настройке этого экземпляра? На мой взгляд ... поскольку SSMS имеет этот набор ONпо умолчанию, я не вижу вреда в настройке этого параметра ONдля всего сервера для всех подключений. В конце концов, мне просто нужен этот SQL Server, чтобы работать выше всего остального.

Эрик Свиггам
источник
Прочитав большую часть моего ответа, на который вы ссылались в этом вопросе, теперь кажется, что он по умолчанию выключен, некоторые клиенты специально включают его, но EF / SqlClient не трогает его, что означает, что он остается выключенным.
Соломон Руцкий
1
Нет EF, но вы поднимаете интересный вопрос о том, как EF может переопределить настройки всего экземпляра. Таким образом, если соединение может переопределить это, очевидно, что наиболее надежным местом для этого набора является соединение, установленное с SQL Server, если это вообще возможно ...
Эрик Свиггам
1
«Всегда устанавливайте ARITHABORT в положение ON в сеансах входа в систему. Если для параметра ARITHABORT установлено значение OFF, это может отрицательно повлиять на оптимизацию запросов, что приведет к проблемам с производительностью». эта статья от Microsoft говорит: docs.microsoft.com/en-us/sql/t-sql/statements/…
Шивангини Шишулкар
Я проверил различные сценарии, мой последний вывод из всего, что этот параметр и сниффинг параметров - приятели. Если есть ARITHABORT OFF, то нормально. Не включайте его для всех входящих подключений. (Удачи, контролирующего это). Но когда соединение приходит с установленным значением ON, SQL генерирует новый план Query, и это может повлиять на производительность. Мой вариант, установите его в качестве пользовательской опции по умолчанию на уровне экземпляра и соответственно настройте запросы.
Эрик Свиггам

Ответы:

11

Есть некоторые значения по умолчанию, которые существуют только потому, что никто не знает, каков будет результат их изменения. Например, сопоставление по умолчанию на уровне экземпляра при установке в системе, в которой в качестве языка операционной системы используется «американский английский» SQL_Latin1_General_CP1_CI_AS. Это не имеет смысла, поскольку параметры SQL_*сортировки предназначены для совместимости до SQL Server 2000. Начиная с SQL Server 2000, вы на самом деле можете выбирать параметры сортировки Windows, поэтому значение по умолчанию для систем на английском языке США должно быть изменено на Latin1_General_CI_AS. НО, я думаю, никто в Microsoft не знает, как это повлияет на все возможные подсистемы, системные хранимые процедуры и т. Д.

Таким образом, я не знаю о каком-либо конкретном негативном влиянии установки его в значение ON как базы данных по умолчанию или даже для всего экземпляра. В то же время я не проверял это. Но даже если бы я его протестировал, я бы все равно не использовал те же пути кода, что и ваше приложение, так что это то, что вам действительно нужно протестировать в вашей среде. Установите этоONна уровне экземпляра в ваших средах разработки и тестирования и посмотрите, как это работает в течение месяца или двух. Затем включите его в Staging / UAT. Если в течение нескольких недель все идет хорошо, измените конфигурацию на «Производство». Ключ должен дать как можно больше времени для тестирования различных путей кода, которые не используются ежедневно. Некоторые поражаются еженедельно или месяцами или ежегодно. Некоторые пути кода затрагиваются только поддержкой, или каким-то специальным отчетом или процедурой поддержки, о которых кто-то создал много лет назад и о которой вам никогда не говорили, а используется только через случайные промежутки времени (нет, этого никогда не бывает ;-).

Итак, я провел некоторое тестирование на экземпляре, который все еще имеет настройку «пользовательских параметров» по ​​умолчанию, поскольку я никогда не менял ее.

Пожалуйста, обратите внимание:

  • @@OPTIONS/ 'user options'является битовой маской
  • 64 бит для 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 .

(это ^символ продолжения строки DOS; .последняя строка просто заставляет дополнительную строку облегчать копирование и вставку)

В LINQPad:

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());
  }
}

ТЕСТ 1: До

SQLCMD возвращает:

master: 0 (ODBC)

LINQPad возвращает:

tempdb: 0 (.Net SqlClient Data Provider)

ИЗМЕНИТЬ ВАРИАНТ ПОДКЛЮЧЕНИЯ ПО УМОЛЧАНИЮ:

Следующий 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;

ТЕСТ 2: После

SQLCMD возвращает:

master: 64 (ODBC)

LINQPad возвращает:

tempdb: 64 (.Net SqlClient Data Provider)

Заключение

Учитывая, что:

  1. Кажется, нет никакой пользы от ARITHABORT OFF
  2. Есть преимущество ARITHABORT ON
  3. Настройка соединения по умолчанию (если не переопределена соединением) = OFF
  4. Не похоже, что ODBC или OLEDB / .NET SqlClient пытаются установить ARITHABORT, поэтому они принимают настройку по умолчанию

Я бы предложил изменить параметры подключения по умолчанию для всего экземпляра (как показано выше). Это было бы менее навязчиво, чем обновление приложения. Я бы обновил приложение, только если вы обнаружите проблему с изменением настроек для всего экземпляра.

PS Я провел простой тест с изменением, tempdbа не с изменением настроек для всего экземпляра, и, похоже, это не сработало.

Соломон Руцкий
источник
1
Да, после прочтения этой темы вопросов и ответов с Полом Уайтом на эту тему кажется, что передача SET ANSI_WARNINGS ON неявно устанавливает ARITHABORT в значение ON. ОДНАКО, если SET ARITHABORT OFF также передается в соединение, даже если ANSI_WARNINGS переопределяет его, SQL-сервер все равно будет «действовать», как ARITHABORT OFF, как при выборе странных планов. Я нахожу это ... ошеломляющим. Таким образом, без сомнения, это должно быть установлено в соединении, а SET ARITHABORT OFF даже не может существовать. Дело закрыто в моих глазах ... sqlservercentral.com/forums/topic/…
Эрик Свиггам
@EricSwiggum Интересная тема, которую вы нашли. Тем не менее, я не понимаю, как вы делаете вывод из этой информации, что она должна быть установлена ​​в соединении. Если ничего в настоящее время не перекрывая его, то мы знаем , что SET ARITHABORT OFFэто не присутствует. Так зачем беспокоиться об этом? единственный случай, когда мы видели, где переопределено значение по умолчанию, это SSMS, устанавливающий его ON(что хорошо). В любом случае я обновил свой ответ тестированием и тем, что я считаю наиболее логичной рекомендацией (согласно имеющейся информации).
Соломон Руцкий
1
Я согласен, включить настройку для всего экземпляра по умолчанию. Но в конечном итоге соединение контролирует то, что установлено. Как насчет случаев совместного использования, когда различные технологии / протоколы подключаются к SQL? Я имею в виду, я должен бегать вокруг и кричать "ЗАКРЫТЬ АРИТАБОРТ" для развития как сумасшедший? или, по крайней мере, способствовать отсутствию ARITHABORT OFF, если это возможно ... Я также нахожу странным, что я не видел, чтобы это дошло до сих пор, мой 6-й год в качестве DBA на полный рабочий день. или, может быть, это случай, когда я не изучил это достаточно сильно. Поддержите меня Пол или Эрланд, LOL, что с этим?
Эрик Свиггам
@EricSwiggum 1) Вам не нужно будет кричать, если вы измените значение уровня экземпляра по умолчанию. 2) Вам нужно будет лишь предупредить отсутствие, ARITHABORT OFF если вы обнаружите какие-либо фактические случаи его возникновения. Пока, вероятно, нет ни одного. 3) Так как это влияет на планы запросов, может случиться так, что в таблицах никогда не было достаточно данных, чтобы у SQL Server были определенные варианты для рассмотрения, где теперь есть больше вариантов, а некоторые плохие. Или, возможно, есть другие переходные факторы, такие как устаревшая статистика и т. Д. Не совсем уверен.
Соломон Руцкий
@EricSwiggum Я не согласен с тобой там. Я думаю, что это очень похоже на то, что я упомянул в начале моего ответа (то есть сопоставление по умолчанию для систем на английском языке США): страх Microsoft перед устаревшими системами, получающими ошибки при обновлении (то есть гарантия обратной совместимости), приносит больше вреда, чем пользы, поскольку это на самом деле увеличивает основание установки / область неидеального сценария. Это делает его растущим притяжением, чтобы остаться в прошлом, и все меньше вероятность того, что все станет лучше. Это те случаи, когда лучше оторвать пластырь и просто покончить с болью.
Соломон Руцкий,