Question

03Cp> J'essaie de diagnostiquer des problèmes de performances apparemment aléatoires avec notre serveur de base de données. Vous trouverez ci-dessous un scénario simplifié, espérons-le générique suffisant pour servir de référence future utile pour quiconque à la recherche de la même réponse.u003C/

03Cp> Supposons que j'ai une table (mysql 5.6 W / Innodb) commeu003C/

CREATE TABLE Example (
    id INT NOT NULL AUTO_INCREMENT,
    secondary_id INT DEFAULT NULL,
    some_data TEXT NOT NULL,
    PRIMARY KEY (id),
    KEY (secondary_id)
) ENGINE=InnoDB;

03Cp> avec environ 15 millions de lignes. Cependant, la colonne secondary_id est de NULL pour presque toutes les lignes, l'indice sur secondary_id a une très faible cardinalité (dans notre cas environ environ 30k). Dans notre cas, lorsque nous vivons la question de la performance, je recherche, la liste de processus du serveur affiche de nombreuses requêtes (100+) de la forme:u003C/

UPDATE Example SET secondary_id = NULL, some_data = '...' WHERE id = 123;

03Cp> qui prennent environ 90 + secondes à compléter, au cours de laquelle elles se trouvent dans la 03Ca href="https://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html" rel="noreferrer">" Mise à jour "Stateu003C/. (Ces requêtes seront exécutées dans des transactions séparées.)u003C/

03Cp> Je me demande spécifiquement si la transition d'un Not-Null secondary_id à un NULL secondary_id provoque des ralentissements de performances de ce qui précède UPDATE. C'est possible que la mise à jour de l'indice dans ce cas prend beaucoup de temps, car il y en a ainsi Beaucoup de lignes (~ 15mil) qui ont la même valeur pour cette colonne (NULL)?u003C/

03Cp> Je suppose que cette question me découle de ne pas comprendre comment l'index de l'arborescence B + stockera les pointeurs de ligne pour des lignes ayant des valeurs d'index en double. Je suppose que ce nœud aurait une liste liée (ou quelque chose de similaire) avec un temps d'insertion assez rapide, alors je devinerais la réponse à ma question est "non". Mais j'aimerais confirmer qu'avec les experts, c'est-à-dire que vous tous.u003C/

03Cp> J'ai essayé de faire de la bonne quantité de recherches ici, mais j'ai monté de jolies mains vides. Le poste le plus complet est probablement 03Ca href="http://hackthology.com/lessons-learned-while-implementing-a-btree.html" rel="noreferrer">Celui-ciu003C/a>, ce qui explique certaines techniques différentes pour la manipulation des clés en double, mais je suis spécifiquement à la recherche d'une approche d'InnoDB / MySQL.u003C/

Était-ce utile?

La solution

03Cp> 90 secondes pour un seul UPDATE sons aussi, trop. Il y a probablement un blocage impliqué et devrait être étudié.u003C/

03Cp> En dehors de cela, avoir une colonne qui a 98% la même valeur (NULL) ne semble pas bonne non plus. Vous devriez envisager de mettre cette colonne dans une table séparée (qui n'aurait que 30 000 rangées). Il compliquerait un peu vos procédures de INSERT/DELETE/UPDATE, mais vous gagneriez probablement des index plus petits. Design suggéré:u003C/

CREATE TABLE Example (
    id INT NOT NULL AUTO_INCREMENT,
    some_data TEXT NOT NULL,
    PRIMARY KEY (id)
) ENGINE = InnoDB ;

CREATE TABLE Example_secondary (
    id INT NOT NULL,
    secondary_id INT NOT NULL,
    PRIMARY KEY (id),
    INDEX (secondary_id),
    FOREIGN KEY (id)
      REFERENCES Example (id)
) ENGINE = InnoDB ;

03Cp> Alors votre UPDATE:u003C/

UPDATE Example 
SET secondary_id = NULL, 
    some_data = '...' 
WHERE id = 123 ;

03Cp> deviendrait:u003C/

BEGIN ;
    UPDATE Example 
    SET some_data = '...' 
    WHERE id = 123 ;

    DELETE FROM Example_secondary 
    WHERE id = 123 ;
COMMIT ;

Autres conseils

03Cp> Qu'est-ce que cela vous donne:u003C/

EXPLAIN UPDATE Example 
    SET secondary_id = NULL, 
        some_data = '...' 
    WHERE id = 123 ;

03Cp> Peut-être que cela donne quelques indices supplémentaires.u003C/

03Cp> Une autre idée: CHANGEMENT INDEX(secondary_id) à INDEX(secondary_id, id). Même si c'est ce qui est stocké dans le BTRee, je me demande s'il serait explicite l'opposerait à être plus efficace. Peut-être que votre index a l'identifiant stocké dans un ordre aléatoire, mais le mien les aurait dans un ordre qui serait efficace pour insérer / trouver / etc.u003C/

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top