Question

Au travail, nous avons deux serveurs. L'un d'eux exécute une application utilisée par de nombreuses personnes et dotée d'un back-end SQL Server 2000. J'ai été libre d'interroger cela pendant longtemps, mais je ne peux rien y ajouter, comme des procédures stockées ou des tables supplémentaires.

Cela nous a conduit à avoir un deuxième serveur SQL lié au premier et à créer une bibliothèque de procédures stockées qui interrogent les données des deux côtés à l'aide d'un serveur lié. Certaines de ces requêtes prennent plus de temps que ce que je voudrais.

Quelqu'un peut-il m'indiquer de bons articles sur l'utilisation de serveurs liés? Je suis particulièrement intéressé à savoir quelles données sont transférées entre les deux, car la plupart des instructions SQL peuvent généralement être exécutées à distance, mais j’ai l’impression qu’il s’agit de transférer les tables complètes, c’est généralement une simple jonction avec une petite finale. table localement.

De plus, quelles sont les options de serveur lié actuellement disponibles:

  • Collation compatible True
  • Accès aux données vrai
  • Rpc True
  • Rpc Out True
  • Utiliser le classement à distance False
  • Nom de classement (vide)
  • Délai de connexion 0
  • Délai d'attente de la requête 0

EDIT:

Je pensais que je mettrais à jour ce post. J'ai utilisé openqueries avec des paramètres dynamiques pendant un certain temps pour améliorer les performances, merci pour le conseil. Cependant, cela peut rendre les requêtes plus compliquées au fur et à mesure que vous finissez par traiter avec des chaînes. enfin cet été, nous avons mis à niveau SQL Server vers 2008 et mis en œuvre la mise en miroir des données en temps réel. Pour être honnête, les requêtes ouvertes approchaient de la vitesse des requêtes locales pour mes tâches, mais la mise en miroir a certainement rendu le SQL plus facile à gérer.

Était-ce utile?

La solution

Je conseillerais les openqueries dynamiques dans une boucle de curseur au lieu de jointures liées. C’est la seule façon pour moi de reproduire les performances de jointure liée de MS Access (au moins pour les tables distantes simples)

Les jointures régulières dans ms sql sont trop inefficaces en tirant tout spécialement dans les énormes tables.

- J'aimerais savoir en quoi les openqueries dans les boucles de curseur sont si mauvaises. si cela est fait correctement, il n'y a pas de problème de verrouillage.

Autres conseils

Évitez les jointures aux tables de serveur liées.

Vous pouvez utiliser un nom en quatre parties pour votre jointure, mais cela coûte plus cher. Votre jointure peut contenir des critères pouvant être utilisés pour limiter le jeu de données du serveur lié et utiliser les colonnes indexées.

Exemple:

SELECT loc.field1, lnk.field1
FROM MyTable loc
INNER JOIN RemoteServer.Database.Schema.SomeTable lnk
  ON loc.id = lnk.id
  AND lnk.RecordDate = GETDATE()
WHERE loc.SalesDate = GETDATE()

Cette requête applique également un critère dans la jointure pouvant être utilisé par le serveur lié avant le calcul de la jointure.

La méthode recommandée consiste à utiliser OPENQUERY.

En évitant la jointure avec l'utilisation de OPENQUERY, le serveur local envoie uniquement la requête à exécuter à distance, à la place d'un ensemble d'ID pour la jointure.

Utilisez le lien pour récupérer un ensemble de données et effectuer les calculs localement. Utilisez une table temporaire (pour les requêtes ad hoc) ou insérez la ligne dans une table permanente dans un travail nocturne.

Les transactions en début peuvent échouer si le coordinateur de transactions à distance est défini sur le serveur de votre choix. Son utilisation consommera plus de ressources.

Notez également que vous frappez un serveur de production exécutant une application, même si vous ne le spécifiez pas, je pense qu’il est prudent de supposer qu’il utilise des transactions lourdes et effectue des insertions et des mises à jour. Vous retirez des ressources de l'application.

Votre utilisation semble être l'utilisation des données à des fins de rapport. Votre serveur peut être configuré pour avoir un journal simple au lieu de complet, ce qui le rend plus efficace.

Vous éviterez également l’annulation de vos requêtes en raison du transfert de données sur le serveur lié. N'oubliez jamais de définir le niveau d'isolation approprié pour vos requêtes et astuces de table, comme NOLOCK.

Et SVP! Ne placez jamais un OPENQUERY (ou un serveur lié) dans une boucle!

Lorsque vous utilisez des serveurs liés pour des jointures de ce type, il est important que le serveur auquel vous êtes immédiatement connecté ("local") soit celui qui contient le plus de données, où le serveur lié ne fournit qu'un petit une partie des données, sinon, oui, il extraira autant de données que nécessaire pour effectuer la jointure.

Les alternatives incluent la copie d’un sous-ensemble de données dans une table temporaire avec autant de travail pour affiner les résultats et tout prétraitement que le serveur lié peut effectuer, puis la jointure sur le fichier "local". côté.

Vous constaterez peut-être que vous pouvez facilement améliorer les performances en inversant la procédure, en vous connectant au serveur sur lequel vous n'avez aucun contrôle (ils doivent créer un serveur lié pour vous), puis en vous connectant au lien. . Si vous devez effectuer un travail important avec les données pour lesquelles vous devez créer des sprocs, transférez-les sur votre serveur et utilisez-les.

Dans certains cas, le serveur lié a tout simplement créé une nuit ce type de résumé qu'il a transmis au serveur local, puis le serveur local a effectué son travail avec la jointure.

Douleur royale

Auparavant, nous avions plusieurs serveurs liés dans notre magasin et il s’est avéré qu’il s’agissait d’un tel PITA .

Tout d’abord, vous avez rencontré de graves problèmes de performances similaires à ce que vous décrivez. J'ai été choqué quand j'ai vu les statistiques d'E / S du réseau. Malgré tous les efforts déployés, nous n’avons pas laissé SQL Server adopter un comportement raisonnable.

Un autre problème résidait dans le fait que les noms de serveur liés aux procs stockés étaient codés en dur partout, sans possibilité de les remplacer. Les développeurs ne pouvaient donc pas facilement tester sur leurs sandbox de développement les fonctionnalités qui touchaient les serveurs liés. Ce fut un obstacle majeur à la création d’une suite de tests unitaires universellement utilisable.

En fin de compte, nous avons complètement abandonné les serveurs liés et transféré la synchronisation des données vers les services Web.

Les requêtes impliquant des semi-jointures sur un serveur lié ont tendance à ne pas être très efficaces. Il vaut peut-être mieux utiliser OPENQUERY pour peupler données dans une table temporaire locale et ensuite travailler à partir de là.

J'ai écrit une application de serveur lié distante dans SQL 2000 il y a quelques années et je suis tombé sur les mêmes problèmes de performances que vous avez décrits. J'ai fini par réécrire plusieurs fois mes procédures stockées afin d'obtenir les meilleures performances.

J'ai beaucoup utilisé les tables temporaires. J'ai trouvé qu'il était moins coûteux de récupérer de grandes quantités de données distantes dans une table temporaire, puis de les joindre, de les manipuler, etc. L'association de tables locales à des tables distantes était très lente, comme vous l'avez décrit.

Afficher le plan d'exécution et afficher le plan d'exécution estimé avaient tendance à aider, même si je ne comprenais pas grand-chose de ce que je cherchais.

Je ne sais pas s'il existe vraiment un moyen efficace d'effectuer ces requêtes avec un serveur distant, car il semble que SQL Server ne puisse pas tirer parti de ses optimisations normales lorsqu'il est utilisé contre un serveur lié. Vous pouvez avoir l'impression de transférer l'ensemble de la table car c'est ce qui se passe réellement.

Je me demande si un scénario de réplication pourrait fonctionner pour vous. En disposant les données sur votre serveur local, vous devriez pouvoir écrire des requêtes normales qui fonctionneront comme vous le souhaitez.

Je ne connais aucun bon article sur lequel vous diriger. Au fur et à mesure que j'écrivais des applications SQL Server plus compliquées, j'ai commencé à penser que j'avais besoin de mieux comprendre le fonctionnement de SQL Server. À cette fin, nous avons acheté la série MS Press Inside Microsoft SQL Server 2005 éditée par Kalen Delaney ici au travail. Volume 1: Le moteur de stockage est sans aucun doute l’endroit idéal pour commencer, mais je n’y suis pas allé aussi loin. Depuis que mes derniers projets n’ont pas impliqué SQL Server, mon étude en est devenue laxiste.

Existe-t-il une possibilité que vous puissiez configurer une base de données distincte sur le serveur plutôt que d'utiliser un serveur lié?

C’est un problème très généreux, qui peut avoir de nombreuses solutions. Mais comme nous avons été témoins de nombreux utilisateurs disant qu'ils ont tout essayé.

Ce qui a résolu mon problème, c'est ..

J'ai mis à niveau SQL Server 2000 de SP2 vers SP4 et, si vous possédez déjà SP4 sur SQL Server 2000, exécutez Instcat.sql. D'après mon expérience, je peux vous assurer que cela fonctionnera à coup sûr si vous êtes épuisé par toutes les autres solutions de contournement.

Merci, Mithalesh mithalesh.gupta@gmail.com

Le SQL dynamique et une fonction peuvent être utilisés pour contourner la question du nom codé en dur. Par exemple, j'essaie une implémentation dans laquelle la fonction ufn_linkedDatabase (@purpose nvarchar (255)) avec l'entrée 'cpi.cpi' (purpose CPI, default-default default) renvoie '[SERVE-NAME.DOMAIN.LCL, 2000]. [CPI]' dans l'environnement de production (où nous utilisons un autre numéro de port pour SQL Server, je ne sais pas pourquoi, y compris dans le nom du serveur lié). Ensuite, une commande SQL est assemblée dans @template varchar (max) avec l'expression @ {cpi.cpi} représentant le serveur lié et la base de données, puis @workstring = REPLACE (@template, N'@{cpi.cpi} ', ...). La manière dont la fonction obtient le nom de la base de données est distincte des procédures - une table de consultation est agréable.

Problèmes - à effectuer avec OPENQUERY (), ce qui est probablement encore préférable, à moins que l'option de serveur lié "collation compatible" est défini sur " true " afin que davantage de tâches puissent être exécutées sur le serveur lié - important même sur un réseau rapide, et que le réseau interne de notre salle des serveurs est respectablement rapide - à faire OPENQUERY () Je dois probablement gérer 'cpi.cpi.server' et ' cpi.cpi.database 'et' cpi.cpi.server.database 'séparément. Et, je pourrais finir par écrire exactement une application en utilisant cette conception, auquel cas elle est trop conçue. Néanmoins, cela signifie que la fonction elle-même ne doit pas forcément être un travail fantaisiste.

De toute façon, résoudre le problème avec du matériel réseau rapide peut être la solution la moins chère.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top