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.