Pourquoi SET ARITHABORT ON accélérerait-il considérablement une requête?

75

La requête est une sélection unique contenant un grand nombre de niveaux de regroupement et d'opérations d'agrégation. SET ARITHABORT ON prend moins d’une seconde, sinon plusieurs minutes. Nous avons vu ce comportement sur SQL Server 2000 et 2008.

Jonathan Allen
la source

Réponses:

62

Un peu daté, mais pour tous ceux qui se retrouvent ici avec un problème similaire ...

J'ai eu le même problème. Pour moi, il s’est avéré qu’il s’agissait d’une détection de paramètre, ce que je ne comprenais pas assez pour commencer. J'ai ajouté un 'set arithabort on' qui corrigeait le problème mais qui revenait ensuite. Puis j'ai lu:

http://www.sommarskog.se/query-plan-mysteries.html

Il a tout effacé. Comme j'utilisais Linq vers SQL et que les options pour résoudre le problème étaient limitées, j'ai finalement utilisé un guide de plan de requête (voir la fin du lien) pour forcer le plan de requête que je voulais.


la source
3
Plus de six ans plus tard, le lien indiqué dans cette réponse est toujours "lecture obligatoire" ... et toujours d'actualité, la dernière révision date de décembre '17.
takrl
30

Les applications .NET se connectent avec l'option désactivée par défaut, mais activée par défaut dans Management Studio. Le résultat est que le serveur met en cache 2 plans d'exécution distincts pour la plupart / toutes les procédures. Cela affecte la manière dont le serveur effectue les calculs numériques. Vous pouvez ainsi obtenir des résultats très différents en fonction de la procédure. Il ne s’agit en réalité que de l’une des deux méthodes les plus courantes utilisées par un proc pour exécuter un plan d’exécution épouvantable, l’autre étant le sniffing de paramètres.

Jetez un coup d'œil à https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance. aspx pour un peu plus de discussion à ce sujet.

Ben Hoffman
la source
Je suis d'accord avec la moitié de cette réponse. Suis très sceptique quant à la revendication de calcul numérique cependant!
Martin Smith
2
@ Martin: Je pense que je n'étais pas clair. Je venais de dire que ARITHABORT ON rend SQL Server une erreur sur toute erreur de débordement div / 0 ou arithmétique. Quand il est éteint, il continue et, pour une raison quelconque, peut causer toutes sortes de problèmes horribles.
@ Ben - Oui, désolé, je ne voulais pas attaquer particulièrement votre réponse. Je faisais simplement remarquer qu'il serait très facile de changer une SEToption, d'obtenir un meilleur plan et de diagnostiquer à tort qu'il s'agit de l'option elle-même qui est en faute. Je ne suis pas convaincu que le type dans votre lien n'a pas fait cela.
Martin Smith
@ Martin - Pas de problème, je ne pensais pas que tu m'attaquais. L'autre discussion que j'ai liée pourrait être un peu floue. J'essayais juste de donner des preuves à l'appui.
@ Martin Après coup, je pense que vous avez raison.
21

Je dirais que c'était presque certainement un paramètre sniffant.

Il est souvent dit que cela SET OPTIONSpeut affecter les performances de cette manière, mais je n'ai pas encore vu de source faisant autorité pour cette revendication, sauf dans le cas où vous utilisez des colonnes indexées Vues / persistées.

Dans ce cas (pour SQL2005 + et sauf si votre base de données est en mode de compatibilité SQL2000 ). Si vous avez les deux ARITHABORTet que ANSI_WARNINGS OFFvous trouverez alors que l'index n'est pas utilisé, il se peut que vous obteniez une analyse plutôt que la recherche souhaitée (et quelques frais généraux car le résultat du calcul persistant ne peut pas être utilisé). ADO.NET semble avoir par défaut ANSI_WARNINGS ONun test rapide que je viens de faire.

L'affirmation de la réponse de Ben selon laquelle "la manière dont le serveur effectue les calculs numériques" peut ajouter des minutes à un résultat qui prendrait autrement moins d'une seconde ne me semble tout simplement pas crédible. Je pense que ce qui a tendance à se produire, c’est que lors de l’examen d’un problème de performances, Profiler est utilisé pour identifier la requête incriminée. Ceci est collé dans le studio de gestion et exécuté et renvoie les résultats instantanément. La seule différence apparente entre les connexions est l' ARITH_ABORToption.

Un test rapide dans une fenêtre du studio de gestion montre que, lorsque l' SET ARITHABORT OFFoption est activée et que la requête est exécutée, le problème de performances se reproduit, de sorte que la casse est apparemment fermée. En effet, cela semble être la méthodologie de dépannage utilisée dans le lien Gregg Stark .

Toutefois, cela ne tient pas compte du fait qu’avec cette option, vous pouvez obtenir le même mauvais plan dans le cache .

Cette réutilisation de plan peut avoir lieu même si vous êtes connecté en tant qu'utilisateur différent de celui utilisé par la connexion d'application.

J'ai testé cela en exécutant d'abord une requête de test à partir d'une application Web, puis à partir de studio de gestion avec SET ARITHABORT OFFet pouvais voir les comptes d'utilisation remonter de la requête ci-dessous.

SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 

Pour que ce partage pf se produise réellement, toutes les clés de cache de plan doivent être identiques. En plus d' arithabortautres exemples, les utilisateurs exécutants ont besoin du même schéma par défaut (si la requête repose sur une résolution de nom implicite) et les connexions nécessitent le même languageensemble.

Une liste plus complète des clés de cache de plan ici

Martin Smith
la source
13

Je sais que je suis en retard à cette fête, mais pour les futurs visiteurs, Martin a tout à fait raison. Nous avons rencontré le même problème: un SP fonctionnait très lentement pour les clients .NET, alors qu'il était très rapide pour SSMS. En explorant et en résolvant le problème, nous avons effectué les tests systématiques que Kenny Evitt demande dans son commentaire à la question de Martin.

En utilisant une variante de la requête de Martin, j'ai cherché le SP dans le cache de procédure et en ai trouvé deux. En regardant les plans, c’est en fait le cas que l’on avait ARITHABORT ON et l’autre ARITHABORT OFF. La version ARITHABORT OFF comportait une recherche d'index, tandis que la version ARITHABORT ON utilisait une analyse d'index pour cette même sortie. Compte tenu des paramètres en jeu, la recherche d'index aurait nécessité une recherche sur des dizaines de millions d'enregistrements pour la sortie.

J'ai effacé les deux procédures du cache et demandé au client .NET d'exécuter à nouveau le SP en utilisant les mêmes paramètres (qui présentaient une plage de dates large pour un client très actif). Le SP est revenu instantanément. Le plan en cache utilisait la même analyse d'index que celle qui était précédemment décrite dans le plan ARITHABORT ON, mais cette fois-ci, le plan était pour ARITHABORT OFF. Nous avons exécuté le SP avec les mêmes paramètres dans SSMS, et nous avons à nouveau obtenu des résultats instantanément. Nous avons maintenant vu qu'un deuxième plan était mis en cache, pour ARITHABORT ON, avec l'analyse d'index.

Nous avons ensuite effacé le cache, exécuté le SP dans SSMS avec une plage de dates étroite et obtenu un résultat instantané. Nous avons constaté que le plan mis en cache résultant avait une recherche d'index, car le même résultat était précédemment traité avec une analyse (ce qui était également une recherche dans le plan d'origine avec ARITHABORT OFF). Encore une fois de SSMS, nous avons exécuté le SP, avec cette fois-ci la même plage de dates et avons constaté les mêmes terribles performances que dans la requête .NET originale.

En bref, cette disparité n’a rien à voir avec la valeur réelle d’ARITHABORT - qu’elle soit activée ou désactivée, l’un ou l’autre client peut obtenir des performances acceptables ou terribles: seuls importaient les valeurs des paramètres utilisés pour la compilation et la mise en cache du plan.

Bien que MSDN indique qu'ARITHABORT OFF lui-même peut avoir un impact négatif sur l'optimisation des requêtes, nos tests confirment que Martin est correct. La cause en était le reniflement des paramètres et le plan résultant n'était pas optimal pour toutes les plages de paramètres.

Mdoyle
la source
1
Je me demande ce que cette phrase Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.signifie. Qu'il s'agisse simplement de l'impossibilité d'utiliser des index sur des colonnes et des vues calculées (si elle ANSI_WARNINGSest également désactivée) ou si cela a effectivement un autre effet.
Martin Smith
Je ne suis pas sûr. Je me demande s’il est tout simplement vrai que quelqu'un chez MSDN a connu une situation similaire, a défini ARTIHABORT sur ON, constaté une amélioration des performances et a tiré les mêmes conclusions que d’autres. En ce qui concerne les vues indexées et les colonnes calculées, je ne suis pas clair. À un moment donné, il est indiqué que les options SET doivent avoir des valeurs spécifiques si une opération INSERT, UPDATE ou DELETE modifie les valeurs de données qui y sont stockées. Ailleurs, ils affirment que l'optimiseur ignorera les index de "toute requête" faisant référence à la vue indexée ou à la colonne calculée. Les deux sont-ils vrais ou est-ce vraiment "toute requête modifiant des données"?
mdoyle
1

Juste eu ce problème. Comme l’ont dit les personnes interrogées ici, la cause première est constituée de plusieurs plans de requête, dont l’un est sous-optimal. Je voulais juste vérifier qu'ARITHABORT pouvait effectivement causer le problème lui-même (car la requête avec laquelle j'avais des problèmes ne contenait aucun paramètre, ce qui supprime la détection de paramètre de l'équation).

Alan D. Nelson
la source
1

Cela me rappelle exactement le même problème que dans les 2008 jours du serveur SQL. Dans notre cas, nous avons soudainement trouvé un travail SQL soudainement ralenti (généralement quelques secondes et maintenant plus de 9 minutes), le travail doit accéder à un serveur lié, nous avons ajouté le paramètre ARITHABORT activé à l'étape de travail, et le problème semblait a été résolu pendant quelques jours puis est revenu.

Nous avons ensuite ouvert un ticket avec le support MS, et au début, ils ne pouvaient pas le savoir non plus. Le ticket a ensuite été transmis à une équipe très expérimentée de PFE. Deux PFE de support ont essayé de résoudre ce problème.

La dernière raison est que les informations d'identification de l'utilisateur (pour exécuter l'étape de travail) ne peuvent pas accéder aux statistiques des tables sous-jacentes (côté serveur lié) et que, par conséquent, le plan d'exécution n'est pas optimisé.

En détail, l’utilisateur n’a pas l’autorisation sur DBCC SHOW_STATISTICS (bien que l’utilisateur puisse effectuer une sélection dans la table). Selon MSDN , cette règle de permission est modifiée après SQL 2012 SP1

Autorisations pour SQL Server et la base de données SQL

Pour afficher l'objet de statistiques, l'utilisateur doit posséder la table ou doit être membre du rôle de serveur fixe sysadmin, du rôle de base de données fixe db_owner ou du rôle de base de données fixe db_ddladmin.

SQL Server 2012 SP1 modifie les restrictions d'autorisation et permet aux utilisateurs disposant de l'autorisation SELECT d'utiliser cette commande. Notez que les conditions suivantes existent pour que les autorisations SELECT soient suffisantes pour exécuter la commande:

Pour vérifier ce problème, il suffit d'exécuter l'éditeur de profil sur l'instance côté serveur lié et d'activer certains événements dans la section "Erreurs et avertissements" comme indiqué ci-dessous.

entrez la description de l'image ici

J'espère que cette expérience pourra aider la communauté d'une manière ou d'une autre.

jyao
la source