SQL Server SÉLECTIONNEZ états provoquer le blocage
Nous utilisons une base de données SQL Server 2005 (pas de contrôle des versions de ligne) avec un énorme instruction select, et nous le voyons bloquer les autres états de l'exécution (vu à l'aide de sp_who2
). Je ne savais pas que les instructions SELECT pourrait provoquer le blocage - est-ce que je peux faire pour atténuer ce risque?
- Utilisez-vous de la hausse des niveaux d'isolation par tout hasard, comme la lecture répétée ou sérialisable? Certains ADO et CLR composants se faufiler dans searializable sans votre consentement explicite... qu'est-Ce que le blocage de ressources sur (touche, la gamme, table) ?
- Je ne suis pas en spécifiant le niveau d'isolation. Est-il un moyen de connaître le niveau d'isolation est en cours d'utilisation?
- Oui, découvrez sys.dm_exec_sessions. transaction_isolation_level colonne.
- Il serait utile d'avoir de la description des tables et des données. Si vous pouvez optimiser la requête puis les serrures seront évidemment être tenu pour une durée plus courte. Une autre option, si elle est en lecture seule opération est de récupérer l'ensemble des données dont vous avez besoin pour fonctionner sur les tables temporaires, puis requête sur les tables temporaires. Vous pouvez remplir l'ensemble de vos tables temporaires en vertu d'un haut niveau d'isolation pour garantir une transactionnel "instantané" des tables live.
Vous devez vous connecter pour publier un commentaire.
SÉLECTIONNEZ pouvez bloquer les mises à jour. Un plan bien conçu le modèle de données de requête et de ne causer que peu de blocage et de ne pas être un problème. Le "comme d'habitude" AVEC indicateur NOLOCK est presque toujours la bonne réponse. La bonne réponse est de régler votre requête afin de ne pas analyser de grandes tables.
Si la requête est untunable alors vous devez d'abord considérer Le niveau d'ISOLATION SNAPSHOT, deuxièmement, vous devriez envisager d'utiliser INSTANTANÉS DE BASE DE DONNÉES et dernière option doit être SALE LIT (et il est préférable de changer le niveau d'isolation plutôt que d'utiliser l'INDICATEUR NOLOCK). Notez que les lectures erronées, comme son nom l'indique clairement, sera de retour les données incohérentes (par exemple. le total de votre feuille peut être déséquilibré).
De documentation:
Un
shared lock
est compatible avec un autre verrou partagé ou d'un verrou de mise à jour, mais pas avec un exclusif de verrouillage.Qui signifie que votre
SELECT
requêtes blocUPDATE
etINSERT
requêtes et vice versa.Un
SELECT
requête place temporaire verrou partagé lorsqu'il lit un bloc de valeurs de la table, et l'enlever quand il fait la lecture.Pour le moment le verrou existe, vous ne serez pas en mesure de faire quelque chose avec les données de la zone verrouillée.
Deux
SELECT
requêtes ne seront jamais bloquer les uns les autres (sauf s'ils sontSELECT FOR UPDATE
)Vous pouvez activer
SNAPSHOT
niveau d'isolation de votre base de données et l'utiliser, mais notez que cela n'empêchera pasUPDATE
requêtes d'être enfermé parSELECT
requêtes (ce qui semble être votre cas).Cependant, permettra d'éviter
SELECT
requêtes d'être enfermé parUPDATE
.Également noter que
SQL Server
, contrairement àOracle
, utilise le gestionnaire de verrous et garde ce qu'il se bloque en mémoire une liste liée.Qui signifie que sous une lourde charge, le simple fait de placer et retirer un verrou peut être lente, puisque la liste liée doit être verrouillé par l'opération de filetage.
Pour effectuer des lectures incorrectes, vous pouvez soit:
ou
n'oubliez pas que vous avez à écrire AVEC (NOLOCK) après chaque table que vous souhaitez sale lire
Vous pouvez définir la le niveau de la transaction Read Uncommitted
Vous pouvez également obtenir des blocages:
"blocages impliquant une seule table"
http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-only-one-table.aspx
et ou des résultats incorrects:
"Sélectionne en vertu de LECTURE ENGAGÉE et REPEATABLE READ peut retourner des résultats incorrects."
http://www2.sqlblog.com/blogs/alexander_kuznetsov/archive/2009/04/10/selects-under-read-committed-and-repeatable-read-may-return-incorrect-results.aspx
Vous pouvez utiliser
WITH(READPAST)
indicateur de table. C'est différent duWITH(NOLOCK)
. Elle permettra d'obtenir des données avant le début de la transaction et ne bloque pas la personne. Imaginez que vous avez exécuté l'instruction avant le début de la transaction.