Requete:
SELECT COUNT(online.account_id) cnt from online;
Mais la table en ligne est également modifiée par un événement. Je peux donc souvent voir le verrouillage en exécutant show processlist
.
Y at-il une grammaire dans MySQL qui peut rendre une instruction select ne causant pas de verrous?
Et j'ai oublié de mentionner ci-dessus qu'il s'agit d'une base de données MySQL esclave.
Après avoir ajouté dans my.cnf:transaction-isolation = READ-UNCOMMITTED
l'esclave rencontrera une erreur:
Erreur 'Enregistrement binaire impossible. Message: Le niveau de transaction 'READ-UNCOMMITTED' dans InnoDB n'est pas sécurisé pour le mode binlog 'STATEMENT' 'dans la requête.
Alors, y a-t-il un moyen compatible de faire cela?
Trouvé un article intitulé "MYSQL WITH NOLOCK"
https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx
dans MS SQL Server, procédez comme suit:
SELECT * FROM TABLE_NAME WITH (nolock)
et l'équivalent de MYSQL est
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
[~ # ~] éditer [~ # ~]
Michael Mior a suggéré ce qui suit (à partir des commentaires)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;
Si la table est InnoDB, voir http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html - il utilise une lecture cohérente (sans verrouillage) mode) pour les sélections "qui ne spécifient pas FOR UPDATE ou LOCK IN SHARE MODE si l'option innodb_locks_unsafe_for_binlog est définie et que le niveau d'isolation de la transaction n'est pas défini sur SERIALIZABLE. Ainsi, aucun verrou n'est défini sur les lignes lues dans la table sélectionnée".
Vous voudrez peut-être lire cette page du manuel MySQL. Le verrouillage d’une table dépend du type de table.
MyISAM utilise des verrous de table pour atteindre une vitesse de lecture très élevée, mais si vous avez une instruction UPDATE en attente, les futurs SELECTS feront la queue derrière la commande UPDATE.
Les tables InnoDB utilisent le verrouillage au niveau de la ligne, et toute la table ne sera pas bloquée derrière une mise à jour. Il existe d’autres types de problèmes de verrouillage associés à InnoDB, mais vous constaterez que cela correspond à vos besoins.
En fonction du type de votre table, le verrouillage fonctionnera différemment, mais SELECT comptera également. Pour les tables MyISAM, un simple compte SELECT (*) FROM ne doit pas verrouiller la table car elle accède aux métadonnées pour extraire le nombre d'enregistrements. Innodb prendra plus de temps car il doit saisir la table dans un instantané pour compter les enregistrements, mais cela ne devrait pas causer de verrouillage.
Concurrent_insert doit au moins être défini sur 1 (valeur par défaut). Ensuite, s'il n'y a pas d '"espace" dans le fichier de données à remplir par la table, des insertions seront ajoutées au fichier et les commandes SELECT et INSERT peuvent se produire simultanément avec les tables MyISAM. Notez que la suppression d'un enregistrement crée une "lacune" dans le fichier de données qui tentera de se remplir d'insertions et de mises à jour futures.
Si vous supprimez rarement des enregistrements, vous pouvez définir concurrent_insert égal à 2 et les insertions seront toujours ajoutées à la fin du fichier de données. Ensuite, les sélections et les insertions peuvent se produire simultanément, mais votre fichier de données ne sera jamais plus petit, quel que soit le nombre d'enregistrements que vous supprimez (à l'exception de tous les enregistrements).
En bout de ligne, si vous avez beaucoup de mises à jour, des insertions et des sélections sur une table, vous devriez en faire InnoDB. Vous pouvez cependant mélanger librement des types de table dans un système.
Les SELECT ne font normalement pas de verrouillage qui vous tient à coeur sur les tables InnoDB. Le niveau d'isolation de transaction par défaut signifie que la sélection ne verrouille pas les éléments.
Bien sûr, la controverse persiste.
une autre façon d'activer la lecture incorrecte dans mysql est d'ajouter un indice: LOCK IN SHARE MODE
SELECT * FROM TABLE_NAME LOCK IN SHARE MODE;
De this référence:
Si vous acquérez un verrou de table explicitement avec LOCK TABLES, vous pouvez demander un verrou READ LOCAL plutôt qu'un verrou READ pour permettre à d'autres sessions d'exécuter des insertions simultanées lorsque la table est verrouillée.