2010-12-01 36 views
5

Nous avons une grande table MyISAM dans laquelle les lignes sont insérées uniquement en bas de la table. En faisant quelques tests, j'ai réalisé que les sélections ne verrouillent pas (toujours) les autres insertions dans cette même table. Cependant, lorsque les inserts proviennent d'une procédure/fonction stockée, ils seront verrouillés par le select.MyISAM Sélectionne les insertions de verrous à l'intérieur de la procédure uniquement

Pourquoi est-ce?

Pour illustrer ce comportement:

CREATE TABLE Foo (
    ID INT NOT NULL AUTO_INCREMENT, 
    Bar VARCHAR(200), 
    PRIMARY KEY(ID)) ENGINE=MyISAM; 

--INSERT into Foo 10M rows 


DELIMITER $$ 

DROP PROCEDURE IF EXISTS InsertProc$$ 

CREATE PROCEDURE InsertProc(IN vBar VARCHAR(255)) 
BEGIN 
    INSERT Foo(Bar) VALUES (vBar); 
END$$ 

DELIMITER ; 

Exécutez la requête suivante:

SELECT Count(*) FROM Foo WHERE INSTR(Bar, 'abcdefg') > 0; 

Bien que le produit est en cours d'exécution, ouvrez une nouvelle connexion et exécuter la requête d'insertion suivante:

INSERT Foo(Bar) VALUES ('xyz1234'); 

Cette insertion va s'exécuter et retourner tout de suite, Cependant, si je cours la requête suivante:

CALL InsertProc('xyz1234'); 

Maintenant, les verrous de requête et attend la sélection pour terminer.

MySql Version: 5.0.51 fonctionnant sur Windows Server 2K3

Merci.

- MISE À JOUR Voici la sortie de profil:

Insert Direct:

(initialization)  0.0000432 
checking permissions 0.0000074 
Opening tables  0.0000077 
System lock   0.0000032 
Table lock   0.0000025 
init     0.000021 
update    0.0002365 
end     0.0000382 
query end   0.000002 
freeing items  0.0000057 
closing tables  0.0000022 
logging slow query 0.0000005 

Insérer par procédure:

(initialization) 0.0000285 
Opening tables 0.0004325 
System lock  0.0000022 
Table lock  0.0002957 
checking permissions 0.0000047 
Opening tables 0.000004 
System lock  0.0000017 
Table lock  3.2365122 
init    0.0000422 
update   0.000251 
end    0.0000025 
query end  0.000003 
closing tables 0.00004 
query end  0.0000074 
freeing items 0.0000074 
logging slow query 0.000001 
cleaning up  0.5790915 

Pourquoi la procédure ouverte et "verrouillage de la table" deux fois ?

+0

Je suis nouveau ici, comment puis-je ajouter une prime à cette question? –

+0

Pouvez-vous expliquer plus si cela cause un problème particulier? – zanlok

+0

@zanlok, Le problème est que nous aurions besoin de déplacer notre code des procédures stockées dans la base de données vers l'application. à moins qu'il y ait un moyen de contourner ce problème de verrouillage –

Répondre

1

MyIASM pour une raison particulière? Les tables InnoDB ont généralement de meilleures caractéristiques de verrouillage.

+0

Oui, il s'agit d'une table d'écriture lourde. nous obtenons de meilleures performances avec MyISAM –

0

Spéculation: la gestion du verrouillage/mutex sur le champ AUTO_INCREMENT sur les tables MyISAM est peut-être plus stricte lorsque des procédures stockées sont utilisées.

Pour l'exclure, pourriez-vous mettre en place un test où ID n'était pas un champ AUTO_INCREMENT? Avez-vous donné INSERT DELAYED une tentative si votre application le permet?

+0

en supprimant le AUTO_INCREMENT n'aide pas. 'INSERT DELAYED' ne fonctionne pas pour nous. –