Vous pouvez activer l' indicateur de trace 7300 qui pourrait vous donner un message d'erreur plus détaillé
Combien de lignes une requête représentative renvoie-t-elle? Quelle est la vitesse / la fiabilité de la connexion réseau entre les deux serveurs?
Il est possible qu'un grand ensemble de données prenne trop de temps à transférer (en plus du temps de requête réel). Vous pouvez augmenter la valeur du délai d'attente.
Vous pouvez essayer de reconfigurer le paramètre de délai d'expiration comme suit:
Définissez le délai de connexion à distance sur 300 secondes:
sp_configure 'remote login timeout', 300
go
reconfigure with override
go
Définissez le délai d'expiration de la requête distante sur 0 (attente infinie):
sp_configure 'remote query timeout', 0
go
reconfigure with override
go
Mise à jour : SQL Server 2012 SP1 et ultérieur : utilisateurs avecSELECT
autorisés auront accès, DBCC SHOW_STATISTICS
ce qui améliorera les performances en lecture seule sur les serveurs liés. Réf: https://msdn.microsoft.com/en-us/library/ms174384(v=sql.110).aspx
Mise à jour : vous avez raison de dire que ce n'est pas la taille des données ou la vitesse de connexion. Cela sonna une cloche dans ma mémoire brumeuse et je me souvins où je l'avais vu: lent dans l'application, rapide dans SSMS? (Un problème avec les serveurs liés). Ce n'est pas le reniflement de paramètres, ce sont les statistiques elles-mêmes qui manquent (en raison des autorisations), ce qui entraîne l'utilisation d'un mauvais plan de requête:
Vous pouvez voir que les estimations sont différentes. Lorsque j'ai couru en tant qu'administrateur système, l'estimation était de 1 ligne, ce qui est un nombre correct, car il n'y a pas de commandes dans Northwind où l'ID de commande dépasse 20000. Mais lorsque j'ai couru en tant qu'utilisateur ordinaire, l'estimation était de 249 lignes. Nous reconnaissons ce nombre particulier comme 30% des 830 commandes, ou l'estimation pour une opération d'inégalité lorsque l'optimiseur n'a aucune information. Auparavant, cela était dû à une valeur de variable inconnue, mais dans ce cas, aucune variable ne peut être inconnue. Non, ce sont les statistiques elles-mêmes qui manquent.
Tant qu'une requête accède uniquement aux tables du serveur local, l'optimiseur peut toujours accéder aux statistiques de toutes les tables de la requête; il n'y a pas de vérification d'autorisation supplémentaire. Mais c'est différent avec des tables sur un serveur lié. Lorsque SQL Server accède à un serveur lié, aucun protocole secret n'est utilisé uniquement pour la communication inter-serveur. Non, SQL Server utilise à la place l'interface OLE DB standard pour les serveurs liés, soit d'autres instances SQL Server, Oracle, des fichiers texte ou votre source de données brassée à la maison, et se connecte comme n'importe quel autre utilisateur. La façon exacte dont les statistiques sont récupérées dépend de la source de données et du fournisseur OLE DB en question. Dans ce cas, le fournisseur est SQL Server Native Client qui récupère les statistiques en deux étapes. (Vous pouvez le voir en exécutant Profiler sur le serveur distant). Tout d'abord, le fournisseur exécute la procédure sp_table_statistics2_rowset qui renvoie des informations sur les statistiques de colonne, ainsi que leur cardinalité et leurs informations de densité. Dans la deuxième étape, le fournisseur exécute DBCC SHOW_STATISTICS, une commande qui renvoie les statistiques de distribution complètes. (Nous examinerons de plus près cette commande plus loin dans cet article.) Voici le problème: pour exécuter DBCC SHOW_STATISTICS, vous devez être membre du rôle serveur sysadmin ou de l'un des rôles de base de données db_owner ou db_ddladmin.
Et c'est pourquoi j'ai obtenu des résultats différents. Lors de l'exécution en tant que sysadmin, j'ai obtenu les statistiques de distribution complètes qui indiquaient qu'il n'y avait pas de lignes avec l'ID de commande> 20000, et l'estimation était une ligne. (Rappelez-vous que l'optimiseur ne suppose jamais zéro ligne de statistiques.) Mais lors de l'exécution en tant qu'utilisateur ordinaire, DBCC SHOW_STATISTICS a échoué avec une erreur d'autorisation. Cette erreur n'a pas été propagée, mais à la place, l'optimiseur a accepté l'absence de statistiques et a utilisé des hypothèses par défaut. Puisqu'il a obtenu des informations de cardinalité, il a appris que la table distante a 830 lignes, d'où l'estimation de 249 lignes.
Chaque fois que vous rencontrez un problème de performances où une requête qui inclut l'accès à un serveur lié est lente dans l'application, mais s'exécute rapidement lorsque vous la testez à partir de SSMS, vous devez toujours rechercher si des autorisations insuffisantes sur la base de données distante pourraient en être la cause. (N'oubliez pas que l'accès au serveur lié peut ne pas être évident dans la requête, mais peut être masqué dans une vue.) Si vous déterminez que les autorisations sur la base de données distante sont le problème, quelles actions pourriez-vous entreprendre?
Vous pouvez ajouter les utilisateurs au rôle db_ddladmin, mais comme cela leur donne le droit d'ajouter et de supprimer des tables, ce n'est pas recommandé.
Par défaut, lorsqu'un utilisateur se connecte à un serveur distant, il se connecte en tant que lui-même, mais vous pouvez configurer un mappage de connexion avec sp_addlinkedsrvlogin, de sorte que les utilisateurs mappent vers un compte proxy qui appartient à db_ddladmin. Notez que ce compte proxy doit être une connexion SQL, donc ce n'est pas une option si le serveur distant n'a pas d'authentification SQL activée. Cette solution est également quelque peu douteuse du point de vue de la sécurité, bien que ce soit mieux la suggestion précédente.
Dans certains cas, vous pouvez réécrire la requête avec OPENQUERY pour forcer l'évaluation sur le serveur distant. Cela peut être particulièrement utile si la requête comprend plusieurs tables distantes. (Mais cela peut également se retourner contre vous, car l'optimiseur obtient désormais encore moins d'informations statistiques du serveur distant.)
Vous pouvez bien sûr utiliser la batterie complète d'indices et de guides de plan pour obtenir le plan que vous souhaitez.
Enfin, vous devez vous demander si cet accès au serveur lié est nécessaire. Peut-être que les bases de données pourraient être sur le même serveur? Les données peuvent-elles être répliquées? Une autre solution?
SELECT
autorisés auront accès,DBCC SHOW_STATISTICS
ce qui améliorera les performances en lecture seule sur les serveurs liés sans avoir à compromettre la sécurité.Que se passe-t-il lorsque vous essayez ceci (c'est-à-dire indiquer explicitement ce qui doit être exécuté sur le serveur distant)?:
Je soupçonne que dans votre cas ci-dessus, SQL Server tire simplement la table entière du serveur distant puis exécute la requête localement (j'ai vu cela se produire plusieurs fois dans le passé). Je préfère être explicite (soit en utilisant OPENQUERY soit en créant un SP sur le serveur distant) donc il n'y a aucun risque de confusion.
la source
Comme il s'agit d'un problème de ressource, le pool de mémoire en dehors du serveur SQL utilisé pour charger des pilotes externes et le CLR peut être proche de sa limite. La valeur par défaut est 256 Mo. Pour contourner ce problème, je vous suggère d'aller dans le gestionnaire de configuration de SQL Server, onglet avancé et d'ajouter l'option -g à la fin des paramètres de démarrage.ie; -g1024 puis de redémarrer le service SQL Server. Je fais généralement cela car nous utilisons un nombre élevé de serveurs liés. http://msdn.microsoft.com/en-us/library/ms190737.aspx
la source
J'ai deux idées qui pourraient aider. Je vais également vous dire que j'ai eu des problèmes de chance avec l'exécution de requêtes sur des serveurs liés. Donc ma première recommandation est de l'éviter si vous le pouvez.
Ma première idée est d'installer la procédure stockée dans la boîte SQL Server 2000, en la faisant référence au serveur local. Vous pouvez ensuite exécuter la procédure stockée à distance.
Si vous pouvez suivre cette voie, cela devrait améliorer considérablement les performances.
Ma deuxième idée est d'obtenir le plan de requête estimé lors de l'exécution de la procédure stockée. Cela vous montre-t-il ce qui prend autant de temps? Un problème potentiel est que le compte que vous utilisez sur le serveur lié peut ne pas avoir suffisamment d'autorité pour obtenir les statistiques de la table (vous avez besoin de plus d'autorité pour le serveur lié que pour le serveur local). Et cela peut ralentir considérablement les requêtes. Vous pouvez en savoir plus sur ce problème particulier ici .
la source