Optimisation requête (Mysql) - SQL/NoSQL - Programmation
Marsh Posté le 27-09-2007 à 16:20:08
Le plus "simple" avec un not exits
Code :
|
La même avec un left outer join + condition à null
Code :
|
Marsh Posté le 27-09-2007 à 16:27:01
Merci pour l'astuce, je teste ça dans un instant !!!
edit : ça marche, mais le traitement reste un peu long
Marsh Posté le 28-09-2007 à 09:50:04
J'ai créé l'index sur le type de document (id_type) et là les effets sont instantanés, je suis tombé à 3 secondes pour la requête, ce qui est largement plus acceptable !
Je repenserais à indexer mes valeurs, merci !
Marsh Posté le 28-09-2007 à 09:51:35
+1 pour les index, parceque là, tu pourras pas faire mieux en terme de requête (la seconde proposé par anajapari étant la meilleure)
Marsh Posté le 28-09-2007 à 09:52:22
moidifie ton index que t'as créé sur "id_type" et rajoute "etat" dans l'index.
Marsh Posté le 28-09-2007 à 10:13:46
MagicBuzz a écrit : +1 pour les index, parceque là, tu pourras pas faire mieux en terme de requête (la seconde proposé par anajapari étant la meilleure) |
en toute théorie elles sont equivalentes puisque l'optimizer est censé convertir la 1ere dans quelque chose de très proche de la deuxième.
Maintenant ça reste mysql ( qui reserve ces surprises) donc je garantis pas que ça soit effectivement le cas
Marsh Posté le 28-09-2007 à 10:17:01
J'aii testé avec Explain justement.
La requête avec le LEFT OUTER JOIN fait au final 2 query de type 'SIMPLE' (c'est l'intitulé de la colonne qui m'est renvoyé ), là où la requête imbriquée fait une requête 'PRIMARY' et une 'DEPENDENT SUBQUERY'. le left outer join fait gagner quelques ms (bon forcément maintenant que c'est indexé j'ai du mal à bien évaluer les écarts de performances).
J'essaie de trouver quelques infos sur ces types de requêtes, pour voir les enjeux en la matière. Préférer des requêtes 'simple' ou pas...
Marsh Posté le 16-11-2007 à 11:02:19
Hello,
Je me permets un petit up pour rester dans le sujet de l'optimisation.
J'ai cette requête qui me pose des soucis :
Code :
|
Explain :
Code :
|
Clé primaire en table a sur article et en table b sur article + pays
Le select n'en finit pas de tourner et se termine par un "killed"
Une idée ?
Marsh Posté le 16-11-2007 à 11:10:17
j'suis jamais certain pour tout ce qui est booléen, donc je mets des parenthèses moi même quand je mixe les AND et OR :
qu'est ce que ça donne si tu modifies ta requête comme ça :
Code :
|
Marsh Posté le 16-11-2007 à 11:38:34
profites-en pour ecrire ta jointure explicitement ( et au passage je l'inverserais):
Code :
|
comme ça toutes tes conditions sont sur la même table.
Par ailleurs si ton champs article est un très grand varchar, tu gagnerais surement s'pas terrible d'utiliser du like %
Marsh Posté le 16-11-2007 à 11:41:37
PunkRod a écrit : j'suis jamais certain pour tout ce qui est booléen, donc je mets des parenthèses moi même quand je mixe les AND et OR :
|
Ca change tout (0.01 sec) !
Merci
C'est la jointure qui semble poser problème, car le même type de requête sur la seule table articles est aussi rapide
Marsh Posté le 16-11-2007 à 11:46:00
@anapajari : merci pour le conseil, c'est vrai que n'ai pas l'habitude d'écrire les jointures de cette façon, par souci de rapidité ...
Quand au like '%' : c'est un varchar(13), et l'utilisation du LIKE est assez aisée (voire obligée) avec ce champ ...
Marsh Posté le 16-11-2007 à 15:45:30
Mosca > C'est pas trop le problème de la jointure le souci (normalement l'optimiseur se débrouille), mais ton "or". Un "or" doit toujours être entre parenthèses, sinon il s'applique quelque soient les "and" autour :
Code :
|
Sélectionne "toutes les personnes actives agées de 20 ans" ET "toutes les personnes de sexe masculin, quelque soit leur age et qu'elles soient actives ou non".
=> En gros ton OR va te faire retourner des millions d'infos. Vu qu'en plus le tiens était sur un "like", ça empêchait l'utilsation des index sur "pays"... Autant dire tu foutais ton SGBD à genoux pour un résultat foireux
Marsh Posté le 27-09-2007 à 15:10:42
Hello,
J'ai la requête suivante qui mets un temps qui me parait invraisemblable (une vingtaine de secondes à être traitée) pour quelques milliers d'enregistrements à parcourir.
Je travaille sur un serveur Mysql 5.
Le but de la requête est d'extraire des documents dans un état particulier, et qui ne doivent pas voir de documents rattachés
(concrètement des factures sans avoirs)
SELECT `id_doc`
FROM `docs`
WHERE `id_type` = '4'
AND `etat` != '7'
AND `id_doc` NOT IN ( SELECT `id_doc_pere`
FROM `docs`
WHERE `id_type` = '5')
ORDER BY `date_echeance` DESC;
Je n'utilise pas régulièrement les requêtes imbriquées, et vu le temps de traitement de la requête, je me demande si je ne devrais pas faire 2 requetes et effectuer mon filtrage via mon langage de programmation.
Est-ce que je m'y prends comme un manche ? ou suis-je limité par autre chose ?
Message édité par PunkRod le 27-09-2007 à 15:10:58