Options de définition de l'indice NOLOCK dans les requêtes de jeu de données

7

Un peu de contexte:
au début, nous avons écrit des rapports juste "directement", sans aucune indication de verrouillage dans les requêtes. Avec les rapports plus volumineux, cela entraînerait parfois des problèmes de verrouillage. Au début, nous y avons remédié en utilisant le WITH (NOLOCK)conseil pour les tables dans la requête.

Parce que (a) c'est assez envahissant, et (b) il est facile d'oublier l'indice pour l'une des tables, nous sommes passés à un deuxième paramètre d'approche TRANSACTION ISOLATION LEVELpour READ UNCOMMITTED(ce qui est bien) en haut de la requête de chaque ensemble de données.

Comme vous pouvez le deviner, il est toujours facile d'oublier l'indice pour l'un des ensembles de données. Cela conduit donc à la question:


Question: Quelles sont les options d'envoi d' NOLOCKindices avec les requêtes de rapport?

PS. Je me rends compte que c'est dans une certaine mesure un problème XY (avec beaucoup de mes autres options pour X, telles que l'optimisation de la requête, ne pas faire de rapport sur la base de données opérationnelle, etc.), mais j'ai essayé d'en faire une question valide sur elle-même néanmoins .


Options:
Voici les options mentionnées ci-dessus, avec des options supplémentaires sur lesquelles je suis curieux de savoir si elles fonctionneraient:

  1. Définissez l' WITH (NOLOCK)indice pour chaque table. (envahissant, très facile à oublier)
  2. Définissez le niveau d'isolement sur READ UNCOMMITTEDpour la requête entière. (toujours facile à oublier)
  3. Est-il possible de spécifier cela au niveau du rapport ? Par exemple, assurez-vous que toutes les requêtes d'ensembles de données pour un rapport seront exécutées sans verrouillage.
  4. Est-il possible de spécifier cela à un autre niveau SSRS ? Par exemple, définissez-le pour un certain dossier de rapport ou en utilisant une extension?
  5. Est-il possible de spécifier cela au niveau de la source de données / chaîne de connexion ? Par exemple, tous les rapports pertinents utilisent-ils une certaine "source de données sans verrouillage"?
  6. Lié à l'option précédente: il est peut-être possible de spécifier un indice de verrouillage par défaut pour un utilisateur "no-lock-sql-user" spécifique (celui qui est utilisé dans la connexion)?
  7. ???

Quelles options sont viables? Y a-t-il des options que j'ai manquées?

Jeroen
la source
Le problème avec le passage à nolocks partout ou la modification de l'isolement pour lire sans engagement dans tous les domaines est un problème de qualité des données. Vous n'obtenez pas seulement des lectures sales, mais vous pouvez potentiellement renvoyer les mêmes données deux fois ou manquer complètement des données. Il peut être préférable d'examiner votre conception et de voir s'il est temps de créer une base de données de rapports distincte. Voir cette question
Mike Walsh
@MikeWalsh a accepté. C'est à cela que j'ai également essayé de me référer dans le morceau sur le problème XY. Pourtant, savoir où et quand il est possible d'utiliser des astuces de verrouillage peut être bénéfique, s'il est utilisé avec soin.
Jeroen

Réponses:

5

Réponses rapides:

  1. Fonctionne, comme vous l'avez noté.
  2. Fonctionne, comme vous l'avez noté.
  3. Cela ne semble pas fonctionner. Je n'ai pas vu d'option à part et chaque fois que cette question est posée, la réponse revient toujours à définir le niveau d'isolement dans la procédure stockée .
  4. Je ne le croirais pas. SSRS est à une couche d'abstraction plus élevée que le moteur de base de données, donc dans un certain sens, il ne se soucie pas du niveau d'isolement - après tout, vous pouvez utiliser des solutions non SGBDR dans vos rapports.
  5. Cela ne fonctionne pas. Vous ne pouvez pas définir le niveau d'isolement dans la chaîne de connexion .
  6. Cela pourrait fonctionner. Vous pouvez créer un déclencheur de connexion .

Il existe quelques options viables si les rapports sont optimisés et posent toujours des problèmes:

  1. Utilisez Always On si vous disposez de SQL 2012. Vous pouvez alors avoir une réplique en lecture seule que vos rapports SSRS pourraient utiliser.
  2. Utilisez la réplication: instantané si vous n'avez pas besoin en temps réel et transactionnel si vous en avez besoin pour être proche du temps réel.
  3. Si vous ne disposez pas du budget pour Always On ou de la patience pour gérer la réplication, effectuez la réplication à bas prix: créez un schéma convivial pour les rapports (c.-à-d. Dénormalisez les tables et mettez-les dans un format qui facilite l'exécution des rapports. ) et utilisez SSIS pour alimenter ce schéma de rapport. Cela fonctionne mieux si vos utilisateurs finaux peuvent vivre avec des données "plus anciennes" (par exemple, la mise à jour toutes les heures ou toutes les 5 minutes). L'inconvénient est que vous allez concevoir le modèle de données deux fois: une fois pour le modèle OLTP et une fois pour le modèle de pseudo-entreposage. L'avantage est que si vous vous dirigez vers un entrepôt de données centralisé, c'est un exercice très utile.
Kevin Feasel
la source
6

Avez-vous envisagé le READ_COMMITTED_SNAPSHOTversionnage des lignes pour la base de données?

Kim Tripp a un bon article à ce sujet sur http://msdn.microsoft.com/en-us/library/ms345124%28v=sql.90%29.aspx

READ_COMMITTED_SNAPSHOTpermet une meilleure fonctionnalité que WITH (NOLOCK)dans la mesure où il offre une cohérence ponctuelle absolue pour les agrégations ou les requêtes de longue durée avec un débit accru en raison de la réduction des conflits de verrouillage.

Max Vernon
la source