LEFT JOIN avec forte cardinalité => tps infini

ViPHP
ViPHP | 1380 Messages

27 avr. 2005, 15:55

Code : Tout sélectionner

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE c index PRIMARY 4 46618 Using index 1 SIMPLE f index PRIMARY 8 686119 Using where; Using index; Not exists
Hum, il utilise ton index mais il ne s'en sert pas (vois le nombre de lignes qu'il doit parcourir dans la deuxième table! Il les lit toutes!)

Essaye de supprimer tes PRIMARY KEYS et d'en faire deux index séparés (pas primary)

Code : Tout sélectionner

ALTER TABLE ´fac´ ADD INDEX id (id) ALTER TABLE ´fac´ ADD INDEX dossier (dossier)
Et refais un EXPLAIN pour voir?

Tu devrais avoir seulement quelques centaines de lignes lues dans ta table ´fac´

S'il l'optimiseur MySQL ne trouve pas tes index, charges les en férocité avec USE INDEX ou FORCE INDEX. Ca DOIT marcher que diable. Et mieux que dans Access :wink:
ripat

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

27 avr. 2005, 16:50

OK c'est bon, merci a tout ceux qui m'ont aidés
Merci particulier à ripat pour la fonction PROCEDURE analyse() qui est super efficasse pour optimiser la structure (mieux vaut l'exécuter sans jointures c'est plus représentatif)

Le fin mot de l'histoire ? ok je vous le donne :
ripat m'en a donné l'idée dans son dernier message : un probleme d'index.
La base a une structure un peu *étrange*, notament au niveau de la table de facturation. Mon boss (qui sais bien faire des requête dans access, mais qui ne connais pas grand chose à SQL) s'est fait refourguer une table avec le primary index mal placé.
table :

Code : Tout sélectionner

n°ligne, Dossier , .... 01,A,... 02,A,... 03,B,... 04,A,...
le numéro de ligne est un auto increment => il a mis le primary index dessus sans tenir compte du numéro de dossier, mais il a quand même mis un index simple sur les dossier, pour accelerer ses requêtes.
Mais dans la (ma) *logique* sql le primary index aurais du être n°ligne+Dossier => quand j'ai optimisé la base j'ai viré les index superflus (en fait il en avais mis un pour chacune des 10 put*ins de colonnes de la table :axe: => j'y suis allé à la hache) et g laissé le primary uniquement

J'avais tenté de mettre un index sur dossier mais ca avais rien changé => j'avais abandonné ....
MAIS, je m'était planté de table, j'avais mis l'index dans la table client au lieu de le mettre dans la table facture #-o :non:

=> parfois je suis une buse !

Moralité, a trop regarder le probleme on fini par ne plus voir l'évidence

en tout cas, re MERCI à tous

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

27 avr. 2005, 17:07

Bon, le mot de la fin pour les fans :
l'ordre des clés dans un index à de l'importance, à la manière des group by.
(c'est stupide mais je m'en souvenais plus / j'y ai pas pensé)

voila ce que me donne le explain sur ma requête de stat pour le nombre de rangs comparés dans la table de facturation :
  • PRIMARY KEY (`Numero`,`Dossier`) => 918134 comparaisons
  • PRIMARY KEY (`Dossier`,`Numero`) => 9181 comparaisons
  • PRIMARY KEY (`Dossier`,`Numero`) + INDEX(`Dossier`) => 32 comparaisons
temps d'exécution de la requête avec les BONS index et les left join (pour mémoire avec les mauvais index et le inner c'était 59sec) :
32sec

FIN

ViPHP
ViPHP | 1380 Messages

27 avr. 2005, 17:18

Si access avait été plus rapide que MySQL, j'en aurais mangé ma souris, mon clavier et, ne soyons pas frugal, mon serveur. :wink:

Et, que donne ton EXPLAIN cette fois? (juste pour mon info)
ripat

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

27 avr. 2005, 17:59

gnarf, moi je mange ma casquette en punition pour ma nullité!
Je suis plus au taf là mais je t'enverrais le EXPLAIN final demain

Moi aussi ca m'étonnais qu'accès soit plus rapide que mysql, mais j'avais fini par croire à un bug de mysql (étrange malgré tout) style boucle infinie, tant j'avais du mal à ouvrir le gestionnaire des taches ...

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

28 avr. 2005, 10:15

Voila le nouvel explain pour ma super requête

Code : Tout sélectionner

1, 'SIMPLE', 's', 'ALL', '', '', , '', 31073, 'Using filesort' 1, 'SIMPLE', 'v', 'ref', 'PRIMARY,Index_dossier', 'Index_dossier', 4, 'f13mdb.s.Dossier', 32, '' 1, 'SIMPLE', 't', 'ref', 'Tarifs23Fev05GHM', 'Tarifs23Fev05GHM', 256, 'f13mdb.s.GHM', 1, '' 1, 'SIMPLE', 'c', 'ref', 'Code', 'Code', 7, 'f13mdb.v.Code acte cetelic', 1, ''
Tient, pendant que j'y pense, ca vous intéresse de savoir faire des tableaux croisés de type MS Access avec mysql ? (ou vous savez déjà ?)
(En passant je suis preneur pour une solution pour PostgreSQL)