4 votes

Trouver les index MySQL sans cardinalité

J'ai récemment trouvé quelques requêtes dans mon journal des requêtes lentes qui auraient dû utiliser des index. Lorsque j'examine les index dans phpmyadmin, la cardinalité est nulle ou vide. Je ne suis pas sûr de la cause de ce phénomène, mais je dois trouver un moyen d'identifier ce problème sans vérifier manuellement plus de 200 tables.

Existe-t-il un script ou une requête que je peux utiliser pour trouver ces index "corrompus" ? Si oui, puis-je forcer une reconstruction de l'index ?

4voto

Adam Points 11

Vous pouvez utiliser INFORMATION_SCHEMA.STATISTICS pour trouver les indices incriminés :

SELECT table_schema,table_name,index_name FROM information_schema.statistics
WHERE CARDINALITY IS NULL AND SEQ_IN_INDEX = 1 AND INDEX_TYPE <> 'FULLTEXT'
AND table_schema NOT IN ('information_schema','mysql');

Vous pouvez utiliser cette requête pour créer le script à exécuter ANALYZE TABLE sur ces tables :

SELECT CONCAT('ANALYZE TABLE ',db,'.',tb,';') FROM
(SELECT table_schema db, table_name tb FROM information_schema.statistics
WHERE CARDINALITY IS NULL AND SEQ_IN_INDEX = 1 AND INDEX_TYPE <> 'FULLTEXT'
AND table_schema NOT IN ('information_schema','mysql')) A;

Voici comment utiliser la requête pour effectuer et exécuter la mise à jour des statistiques de l'index :

SQLSTMT="SELECT CONCAT('ANALYZE TABLE ',db,'.',tb,';') FROM"
SQLSTMT="${SQLSTMT} (SELECT table_schema db, table_name tb FROM "
SQLSTMT="${SQLSTMT} information_schema.statistics"
SQLSTMT="${SQLSTMT} WHERE CARDINALITY IS NULL AND SEQ_IN_INDEX = 1"
SQLSTMT="${SQLSTMT} AND INDEX_TYPE <> 'FULLTEXT'"
SQLSTMT="${SQLSTMT} AND table_schema NOT IN ('information_schema','mysql')) A"
mysql -u... -p... -ANe"${SQLSTMT}" > AnalyzeTablesWithNoCardinalities.sql
mysql -u... -p... < AnalyzeTablesWithNoCardinalities

CAVEAT

N'oubliez pas que tous les niveaux d'un index n'ont pas forcément une cardinalité. Notez tous que j'ai seulement choisi SEQ_IN_INDEX = 1 signifie que je n'ai regardé que les index dont la première colonne indexée n'a pas de cardinalité. Cela peut s'appliquer aux colonnes PRIMARY KEY dans certains cas.

3voto

Noodles Points 1336

Dans le prolongement de ce que Rolando a posté ci-dessus. Cela élimine toutes les tables vides de la liste de cardinalité de l'index NULL.

SELECT s.table_schema, s.table_name, s.index_name
FROM information_schema.statistics AS s
INNER JOIN information_schema.tables AS t ON s.table_schema = t.table_schema AND s.table_name = t.table_name
WHERE t.TABLE_ROWS <> 0 AND s.CARDINALITY IS NULL AND s.SEQ_IN_INDEX = 1 AND s.INDEX_TYPE <> 'FULLTEXT'
AND s.table_schema NOT IN ('information_schema','mysql') AND t.ENGINE <> 'MEMORY';

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X