J'ai un très grand ensemble de données (environ 3 millions d'enregistrements) qui doivent être fusionnés avec des mises à jour et de nouveaux enregistrements sur un calendrier quotidien. J'ai une procédure stockée qui brise réellement l'enregistrement défini en 1000 morceaux d'enregistrement et utilise la commande Je recherche des suggestions, des meilleures pratiques ou des exemples sur la manière de fusionner de grands ensembles de données sans verrouiller les tables. P>
merci p> fusion code> avec des tables temporaires pour éviter de verrouiller la table en direct pendant la mise à jour des données. Le problème est que cela ne vous aide pas exactement. La table est toujours "verrouille" et notre site Web utilisant les données reçoivent des délais d'attente lors de la tentative d'accès des données. J'ai même essayé de le diviser dans 100 morceaux de disques et j'ai même essayé un
Waitfor Delay '000: 00: 5' Code> Pour voir si cela contribuerait à faire une pause entre la fusion des morceaux. C'est encore plutôt paresseux. P>
3 Réponses :
Changez votre extrémité avant pour utiliser Nolock ou lire non programmée lorsque vous effectuez la Vous ne pouvez pas Nolock Fusionner, insérer ou mettre à jour, car les enregistrements doivent être verrouillés afin d'effectuer la mise à jour. Cependant, vous pouvez nolockner les SELECTS. P>
Notez que vous devez l'utiliser avec prudence. Si des lectures sales vont bien, allez-y. Toutefois, si les lectures nécessitent les données mises à jour, vous devez descendre un chemin différent et déterminer exactement pourquoi la fusion des enregistrements 3M provoque un problème. p>
Je serais prêt à parier que la plupart du temps est consacré à la lecture de données du disque pendant la commande de fusion et / ou de travailler autour de situations de mémoire faible. Vous risquez peut-être mieux de faire de plus en plus de RAM dans votre serveur de base de données. p>
Un montant idéal serait d'avoir suffisamment de RAM pour tirer toute la base de données en mémoire si nécessaire. Par exemple, si vous avez une base de données de 4 Go, assurez-vous que 8 Go de RAM .. Dans un serveur X64 bien sûr. P>
Le Nolock n'est pas une option avec les SELECTS. Le code utilise NHibernate, et même après avoir défini NHibernate pour n'utiliser aucun verrou, il est encore temps de sortir. Nous avons ajouté plus de RAM sur le serveur et nous avons dirigé le profilier SQL et nous avons fait des améliorations qui auront une augmentation de l'efficacité de 41%. Merci pour vos suggestions, Chris.
@JOSH: La seule raison pour laquelle les délais d'attente tout en utilisant Nolocks est si le serveur est simplement martelé pour des ressources et fait beaucoup d'accès au disque. En d'autres termes, elle est liée à cause du manque de mémoire. Les trois choses que vous devez faire sont: profilant et réparer les requêtes, ajout de la RAM (vous avez fait ces) et modifier potentiellement les lecteurs pour utiliser quelque chose qui est beaucoup plus rapide. Cependant, le plus grand impact provient des mises à jour de l'index et de la RAM.
J'ai fini par dumping la déclaration de fusion en faveur des mises à jour et des insertions explicites. Lorsque vous combinez cela avec le fractionnement de 1000 enregistrements à une époque, il est à la fois plus rapide et ne verrouille pas le fichier de page comme la fusion. Merci encore pour vos suggestions. Ils nous aident!
@Josh: content que cela ait aidé à vous conduire à une solution. Je vais devoir vérifier notre propre usage de fusion pour voir si nous avons des problèmes similaires sur les mises à jour de masse que nous faisons. Je n'ai pas encore vu de problèmes, mais l'un de nos produits est sur le point d'être intensifié par un facteur de 10 afin que cela puisse être une bonne pratique à tester.
Pouvez-vous confirmer que - dans une instruction Fusion SQL, nous pouvons utiliser la table Nolock sur la source de sorte que la table source ne soit pas verrouillée?
J'ai peur d'avoir une expérience opposée. Nous effectuions des mises à jour et des insertions où la table source n'avait qu'une fraction du nombre de lignes que la table cible, qui était dans les millions de personnes. p>
Lorsque nous avons combiné les enregistrements de la table source dans toute la fenêtre opérationnelle, puis effectué la fusion une seule fois, nous avons vu une augmentation de 500% de la performance. Mon explication est que vous payez pour l'analyse initiale de la commande de fusion une fois au lieu de encore et encore une fois dans une boucle serrée. P>
En outre, je suis certain que la fusion de 1,6 million de rangées (source) dans 7 millions de lignes (cible), par opposition à 400 lignes dans 7 millions de lignes sur 4 000 opérations distinctes (dans notre cas) exploite les capacités du moteur SQL Server. beaucoup mieux. Encore une fois, une bonne quantité du travail est dans l'analyse des deux ensembles de données et cela n'est effectué qu'une fois. P>
Une autre question que je dois demander est de savoir si vous savez que la commande de fusion fonctionne beaucoup mieux avec des index sur les tables source et cibles? Je voudrais vous référer au lien suivant: p>
http://msdn.microsoft.com /en-us/library/cc879317(V=SQL.100).aspx p>
De l'expérience personnelle, le principal problème de la fusion est que, puisqu'il verrouille la page, il exclut toute concurrence dans vos inserts dirigés vers une table. Donc, si vous descendez cette route, il est fondamental que vous lotez toutes les mises à jour qui frapperont une table dans un seul écrivain. P>
Par exemple: Nous avions une table sur laquelle l'insert a pris une foule de 0,2 seconde par entrée, la majeure partie de cette période étant apparemment gaspillée sur le verrouillage des transactions, nous avons donc changé cela pour utiliser la fusion et que certains tests rapides ont montré que cela nous a permis de Insérez 256 entrées en 0,4 seconde, voire 512 en 0,5 seconde, nous avons testé cela avec des générateurs de charge et tout semblait bien, jusqu'à ce qu'il frappe la production et tout bloqué en enfer sur les serrures de la page, ce qui a entraîné un débit total beaucoup plus bas qu'avec le Inserts individuels. P>
La solution consistait à classer non seulement les entrées d'un seul producteur dans une opération de fusion, mais également à lotter le lot de producteurs allant à une DB individuelle dans une seule opération de fusion via un niveau de file d'attente supplémentaire (précédemment également une seule connexion. par dB, mais en utilisant Mars pour interlaisser tous les producteurs appellent à la procédure stockée effectuant la transaction de fusion réelle), de cette façon, nous avons ensuite été capables de gérer plusieurs milliers d'inserts par seconde sans problème. P>
Avoir les indications Nolock sur toutes vos lectures frontales est un must absolu, toujours. P>
Y a-t-il un moyen d'utiliser Nolock avec fusion? Les données sont uniquement lues à partir du site et uniquement mises à jour par le processeur de backend. Je n'ai donc pas besoin de verrouillage.
Avez-vous reçu un moyen de ne pas verrouiller la table source de la déclaration de fusion SQL?