Quelles sont les ramifications de l'activation d'ARITHABORT pour toutes les connexions dans SQL Server?


10

J'ai donc déterminé que le comportement erratique de mon SQL Server est dû au paramètre par défaut du fournisseur de données .Net SqlClient SET ARITHABORT OFF. Cela dit, j'ai lu divers articles qui débattent de la meilleure façon de mettre en œuvre cela. Pour moi, je veux juste un moyen facile parce que SQL Server souffre et que le réglage de ma requête n'a pas complètement transcendé dans l'application (et évidemment, l'ajout SETd'un dans un sp ne fonctionne pas).

Dans le brillant article d' Erland Sommarskog sur le sujet, il suggère essentiellement d'adopter une approche sûre en modifiant l'application à émettre SET ARITHABORT ONpour la connexion. Cependant, dans cette réponse d'une question dba.stackexchange , Solomon Rutzky propose à la fois une approche à l'échelle de l'instance et à l'échelle de la base de données.

Quelles sont les ramifications qui me manquent ici avec la définition de cette instance à l'échelle? Comme je le vois ... puisque SSMS a cet ensemble ONpar défaut, je ne vois aucun mal à définir ce ONserveur pour toutes les connexions. À la fin de la journée, j'ai juste besoin de ce serveur SQL pour fonctionner avant tout.


En lisant une grande partie de ma réponse que vous avez liée à la question, il semble maintenant qu'elle soit désactivée par défaut, certains clients l'activent spécifiquement, mais EF / SqlClient ne la touche pas, ce qui signifie qu'elle reste désactivée.
Solomon Rutzky

1
Pas d'EF, mais vous soulevez un point intéressant sur la façon dont EF peut remplacer le paramètre à l'échelle de l'instance. Donc, si une connexion peut remplacer cela, évidemment l'endroit le plus fiable pour avoir cet ensemble est à partir de la connexion qui est établie avec SQL Server, si possible ...
Eric Swiggum

1
"Définissez toujours ARITHABORT sur ON dans vos sessions de connexion. La définition d'ARITHABORT sur OFF peut avoir un impact négatif sur l'optimisation des requêtes, entraînant des problèmes de performances." cet article de Microsoft dit: docs.microsoft.com/en-us/sql/t-sql/statements/…
Shiwangini Shishulkar

J'ai testé divers scénarios, ma conclusion finale est que ce réglage et le reniflage des paramètres sont des compagnons de lit. Si c'est le cas ARITHABORT OFF, alors très bien. Gardez-le éteint pour toutes les connexions entrantes. (Bonne chance pour contrôler ça). Mais lorsqu'une connexion arrive avec elle définie sur ON, SQL génère un nouveau plan de requête et cela peut affecter les performances. Ma prise, définissez-la sur ON comme option utilisateur par défaut au niveau de l'instance et ajustez les requêtes en conséquence.
Eric Swiggum

Réponses:


11

Il y a des défauts qui existent simplement parce que personne ne sait vraiment quel serait l'effet de les changer. Par exemple, le classement au niveau de l'instance par défaut lors de l'installation sur un système qui utilise "US English" comme langue du système d'exploitation SQL_Latin1_General_CP1_CI_AS. Cela n'a aucun sens puisque les SQL_*classements sont pour la compatibilité pré-SQL Server 2000. À partir de SQL Server 2000, vous pouvez réellement choisir un classement Windows, et la valeur par défaut pour les systèmes en anglais américain aurait donc dû être remplacée par Latin1_General_CI_AS. MAIS, je suppose que personne chez Microsoft ne sait vraiment quel sera l'impact sur tous les différents sous-systèmes potentiels et procédures stockées, etc.

Donc, je ne suis au courant d'aucun impact négatif spécifique de sa définition sur ON comme valeur par défaut de la base de données ou même à l'échelle de l'instance. En même temps, je ne l'ai pas testé. Mais même si je l'avais testé, je n'utiliserais peut-être pas les mêmes chemins de code que votre application, c'est donc quelque chose que vous devez vraiment tester dans votre environnement. Réglez-le surONau niveau de l'instance dans vos environnements Dev et QA et voyez comment cela fonctionne pendant un mois ou deux. Activez-le ensuite dans Staging / UAT. Si tout se passe bien pendant plusieurs semaines, passez ce changement de configuration à Production. La clé est de donner autant de temps que possible pour tester différents chemins de code qui ne sont pas touchés quotidiennement. Certains sont frappés chaque semaine ou mois ou annuellement. Certains chemins de code ne sont atteints que par le support, ou par un rapport ad hoc ou un processus de maintenance que quelqu'un a créé il y a des années et ne vous en a jamais parlé et n'est utilisé qu'à des intervalles aléatoires (non, cela ne se produit jamais ;-).

J'ai donc fait des tests sur une instance qui a toujours le paramètre par défaut "options utilisateur" car je ne l'ai jamais changé.

Notez s'il vous plaît:

  • @@OPTIONS/ 'user options'est une valeur masquée par bit
  • 64 est le bit pour ARITHABORT ON

INSTALLER

J'ai testé à la fois SQLCMD (qui utilise ODBC) et LINQPad (qui utilise .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 .

(le ^est le caractère de continuation de la ligne DOS; le .sur la dernière ligne est juste pour forcer la ligne supplémentaire pour faciliter le copier-coller)

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

TEST 1: Avant

SQLCMD renvoie:

master: 0 (ODBC)

LINQPad renvoie:

tempdb: 0 (.Net SqlClient Data Provider)

MODIFIER L'OPTION DE CONNEXION PAR DÉFAUT:

Le T-SQL suivant permet ARITHABORTsans supprimer d'autres options qui pourraient être définies et sans rien changer s'il ARITHABORTest déjà défini dans la valeur masquée par bit.

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;

TEST 2: Après

SQLCMD renvoie:

master: 64 (ODBC)

LINQPad renvoie:

tempdb: 64 (.Net SqlClient Data Provider)

Conclusion

Étant donné que:

  1. Il ne semble y avoir aucun avantage à avoir ARITHABORT OFF
  2. Il y a avantage à avoir ARITHABORT ON
  3. Le paramètre de connexion par défaut (sauf s'il est remplacé par la connexion) = OFF
  4. Il ne semble pas que ODBC ou OLEDB / .NET SqlClient tentent de définir ARITHABORT, donc ils acceptent le paramètre par défaut

Je suggère de modifier les options de connexion par défaut à l'échelle de l'instance (comme indiqué ci-dessus). Ce serait moins gênant que la mise à jour de l'application. Je ne mettrais à jour l'application que si vous rencontrez un problème avec la modification du paramètre à l'échelle de l'instance.

PS J'ai fait un test simple avec changer tempdbet ne pas changer le paramètre à l'échelle de l'instance et cela ne semble pas fonctionner.


1
Huh, après avoir lu ce Q&A avec Paul White sur le sujet, il semble que passer SET ANSI_WARNINGS ON, définit implicitement ARITHABORT sur ON. CEPENDANT, si SET ARITHABORT OFF est également passé dans la connexion, même avec ANSI_WARNINGS le remplaçant, SQL Server "agira" toujours comme ARITHABORT est OFF, comme dans le choix de plans étranges. Je trouve ça ... ahurissant. Donc, sans aucun doute, cela doit être défini dans la connexion ET SET ARITHABORT OFF ne peut même pas exister. Affaire close à mes yeux ... sqlservercentral.com/forums/topic/…
Eric Swiggum

@EricSwiggum Discussion intéressante que vous avez trouvée. Cependant, je ne vois pas comment vous concluez à partir de cette information qu'elle doit être définie dans la connexion. Si rien ne l'emporte actuellement, alors nous savons que ce SET ARITHABORT OFFn'est pas le cas . Alors pourquoi s'inquiéter de sa présence? la seule instance où nous avons vu où la valeur par défaut est remplacée est SSMS la définissant sur ON(ce qui est une bonne chose). Quoi qu'il en soit, j'ai mis à jour ma réponse avec des tests et ce que je considère comme la recommandation la plus logique (selon les informations existantes).
Solomon Rutzky

1
Je suis d'accord, activez le paramètre à l'échelle de l'instance par défaut. Mais finalement, la connexion contrôle ce qui est défini. Qu'en est-il du cas des instances partagées où diverses technologies / protocoles se connectent à SQL? Je veux dire, dois-je courir et crier "SET ARITHABORT ON" au développement comme un fou? ou à tout le moins, promouvoir l'absence d'ARITHABORT OFF si possible .. Je trouve également étrange que je ne l'ai pas vu jusqu'à présent, ma 6e année en tant que DBA à temps plein. ou peut-être que c'est un cas où je n'y ai pas suffisamment réfléchi. Soutenez-moi Paul ou Erland, LOL, qu'est-ce qui se passe?
Eric Swiggum

@EricSwiggum 1) Vous n'auriez pas besoin de crier quoi que ce soit si vous modifiez la valeur par défaut au niveau de l'instance. 2) Vous n'auriez besoin de promouvoir l'absence de ARITHABORT OFF si vous en trouvez des incidences réelles. Jusqu'à présent, il n'y en a probablement pas. 3) Étant donné que cela affecte les plans de requête, il se peut que les tables n'aient jamais eu suffisamment de données pour que SQL Server ait certains choix à considérer, où il y a maintenant plus de choix et certains sont mauvais. Ou peut-être qu'il existe d'autres facteurs transitoires, tels que des statistiques obsolètes, etc. Pas tout à fait sûr.
Solomon Rutzky

@EricSwiggum Je ne suis pas en désaccord avec vous là-bas. Je pense que cela est très similaire à ce que j'ai mentionné au début de ma réponse (c'est-à-dire le classement par défaut pour les systèmes en anglais américain): la crainte de Microsoft que les systèmes hérités obtiennent des erreurs lors de la mise à niveau (c'est-à-dire la garantie de compatibilité descendante) fait plus de mal que de bien car il s'agit en fait augmente la base d'installation / la portée du scénario non idéal. Cela en fait une attraction toujours croissante pour rester dans le passé, et une chance toujours décroissante que les choses s'améliorent. Ce sont des cas où il est préférable d'arracher le pansement et de simplement en finir avec la douleur maintenant.
Solomon Rutzky
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.