Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD
PHP & SGBD Forum d'entraide sur les SGBD avec PHP. Avant de poster : FAQ BDD, toutes les FAQ PHP, cours BDD et sources BDD
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/12/2007, 14h29   #1
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
Par défaut [SQL] Optimisation d'une requête

Hello,

Pour un système de pagination, je calcul mes pages en fonction du nombre max de records dans la bd.

Seulement, je me demande si il n'est pas possible de ne faire qu'une seule requête au lieu de 2?

J'en ai une avec le LIMIT x, y

Et l'autre identique sans le LIMIT qui me retourne le nombre max d'élément.

N'est-il pas possible d'obtenir le nombre max avec la première requête


Exemple de requête:

SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type="gallery" AND g.status=1 AND ((g.access<=20 AND g.accessType=0) LIMIT 0, 2

SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type="gallery" AND g.status=1 AND ((g.access<=20 AND g.accessType=0)

Merci beaucoup.
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2007, 15h16   #2
Rédacteur
 
Avatar de wamania
 
Développeur Web
Inscription : juillet 2003
Messages : 676
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : juillet 2003
Messages : 676
Points : 678
Points : 678
que je sache, ce n'est pas possible.
Par contre ton code est optimisable

1) ceci est la partie commune
Code :
$common_sql = "FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type='gallery' AND g.status=1 AND ((g.access<=20 AND g.accessType=0)";
(il est préférable de mettre les quotes comme je les ai mis et non l'inverse)

2) Calcul du total
Au lieux de tout braser, utilise le SQL !!!
Code :
$total_sql = "SELECT COUNT(*) as nb ".$common_sql;
tu auras directement le nombre voulu dans nb

3) enfin la dernière, telle que tu l'as faite
Code :
$page_sql = "SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description ".$common_sql." LIMIT 0, 2";
__________________
Articles sur developpez.com
- Gestion des exceptions avec PHP5
- Chiffrement et hash en PHP contre l'attaque Man in the middle
- Aedituus - Espace membre sécurisé en PHP5

Lithium : ORM ActiveRecord PHP5 extrêmement léger
wamania est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2007, 15h21   #3
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
OK merci pour cette correction

Seulement petite question:

Pourquoi inverser les quotes???

Justement j'ai construit mes requêtes avec des ' ' au lieu de " " pour que PHP n'interprète pas le contenu de la requête et donc ainsi gagner du temps d'execution.
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2007, 15h26   #4
Rédacteur
 
Avatar de wamania
 
Développeur Web
Inscription : juillet 2003
Messages : 676
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : juillet 2003
Messages : 676
Points : 678
Points : 678
Citation:
Justement j'ai construit mes requêtes avec des ' ' au lieu de " " pour que PHP n'interprète pas le contenu de la requête et donc ainsi gagner du temps d'execution.
Oui, mais si on fait généralement ça pour PHP/HTML, c'est pour la lisibilité, et aussi la perf.
les attributs HTML sont logiquement entourés de ", il est donc plus simple de faire
Code :
1
2
 
echo '<tag att="toto">titi</tag>';
Par contre, les string dans les requètes MySQL doivent être entourés de ' , il est donc plus simple d'écrire
Code :
$sql = "SELECT toto FROM titi WHERE tata='tutu'";
L'idée majeur étant finalement la lisibilé, même si les perf peuvent éventuellement compter
__________________
Articles sur developpez.com
- Gestion des exceptions avec PHP5
- Chiffrement et hash en PHP contre l'attaque Man in the middle
- Aedituus - Espace membre sécurisé en PHP5

Lithium : ORM ActiveRecord PHP5 extrêmement léger
wamania est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2007, 15h32   #5
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
Un grand merci pour ces précisions
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2007, 21h22   #6
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
Les requêtes et le COUNT(*) marchent très bien excepté pour une requête un peu plus complexe où le COUNT(*) me retourne 3 au lieu de 1.

Voici ma requête:

Code :
1
2
3
4
$query=$query_search_pages='SELECT DISTINCT p.id, pc.title, p.date';
$common_query='FROM pages AS p INNER JOIN pages_content AS pc ON p.id=pc.pageId INNER JOIN pages_lines_content AS plc ON pc.pageId=plc.pageId WHERE (pc.title LIKE "%' . $keywords . '%" OR plc.content_left LIKE "%' . $keywords . '%" OR plc.content_center LIKE "%' . $keywords . '%" OR plc.content_right LIKE "%' . $keywords . '%") AND pc.languageId=' . (int)$_SESSION['language_id'] . ' AND plc.languageId=' . (int)$_SESSION['language_id'] . '  AND p.access <= ' . (int)$_SESSION['access'] . ' AND p.status=1 AND((Now() BETWEEN p.dateStart AND p.dateEnd) OR (p.dateStart="0000-00-00" AND p.dateEnd="0000-00-00"))' . $orderBy;
 
 $all = mysql_request('SELECT  DISTINCT COUNT(*) AS nb' . ' ' . $common_query);
Comment ce fait-il que je n'obtienne pas le même nombre de ligne avec la première requête et celle du COUNT(*) ?

Pourtant la requête commune est identique ? (logique)

Un grand merci pour vos lumières...
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2007, 14h16   #7
Membre confirmé
 
Avatar de UNi[FR]
 
nico.
Inscription : juin 2002
Messages : 327
Détails du profil
Informations personnelles :
Nom : nico.
Âge : 28

Informations forums :
Inscription : juin 2002
Messages : 327
Points : 294
Points : 294
Envoyer un message via MSN à UNi[FR]
Citation:
Envoyé par wamania Voir le message
que je sache, ce n'est pas possible.
...
2) Calcul du total
Au lieux de tout braser, utilise le SQL !!!
Code :
$total_sql = "SELECT COUNT(*) as nb ".$common_sql;
tu auras directement le nombre voulu dans nb
...

Il faut éviter les SELECT COUNT(*) et mettre à la place SELECT COUNT(id) c'est un gain en performance qui est important sur les grosse BDD
__________________
Gnarf !
www.uni-d.net (Wamp MSS) - Mon C.V. - Mon Blog
.NET {VS 2010 && LINQ} && PHP {(Zend Studio || Notepad++) && (WAMP || WAMP mss)} && Multimédia {Flash CS5 && Photoshop CS5}

Pensez au TAG
UNi[FR] est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2007, 14h51   #8
Rédacteur
 
Avatar de wamania
 
Développeur Web
Inscription : juillet 2003
Messages : 676
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : juillet 2003
Messages : 676
Points : 678
Points : 678
oui c'est vrai
enfin dans ton cas je dirais COUNT(p.id)
__________________
Articles sur developpez.com
- Gestion des exceptions avec PHP5
- Chiffrement et hash en PHP contre l'attaque Man in the middle
- Aedituus - Espace membre sécurisé en PHP5

Lithium : ORM ActiveRecord PHP5 extrêmement léger
wamania est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2007, 15h10   #9
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 797
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 797
Points : 1 688
Points : 1 688
Code :
Il faut éviter les SELECT COUNT(*) et mettre à la place SELECT COUNT(id) c'est un gain en performance qui est important sur les grosse BDD
T'es sûr de ton coup il me semblait justement que le count(*) était optimisé pour ca ? (ca doit être écrit quelquepart dans la doc...).
D'autre part tu peux utiliser SQL_CALC_FOUND_ROWS et FOUND_ROWS() si t'es en >=4.0, pour effectuer une seule requête.
Bye

[edit]Ah nan en fait c'est juste optimisé pour les requêtes sans where le count(*)
[/edit]
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2007, 21h47   #10
Rédacteur
 
Avatar de wamania
 
Développeur Web
Inscription : juillet 2003
Messages : 676
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : juillet 2003
Messages : 676
Points : 678
Points : 678
on en apprend tous les jours.
Merci pour ces infos Djakisback, en effet, c'est super pratique
__________________
Articles sur developpez.com
- Gestion des exceptions avec PHP5
- Chiffrement et hash en PHP contre l'attaque Man in the middle
- Aedituus - Espace membre sécurisé en PHP5

Lithium : ORM ActiveRecord PHP5 extrêmement léger
wamania est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2007, 08h45   #11
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
Donc il vaut mieux utiliser un COUNT(id) et non un COUNT(*) ?
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2007, 08h48   #12
Rédacteur
 
Avatar de wamania
 
Développeur Web
Inscription : juillet 2003
Messages : 676
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : juillet 2003
Messages : 676
Points : 678
Points : 678
en fait, comme l'a dit Djakisback, regarde plutôt dans la doc MySQL les fonctions :
Citation:
D'autre part tu peux utiliser SQL_CALC_FOUND_ROWS et FOUND_ROWS() si t'es en >=4.0
__________________
Articles sur developpez.com
- Gestion des exceptions avec PHP5
- Chiffrement et hash en PHP contre l'attaque Man in the middle
- Aedituus - Espace membre sécurisé en PHP5

Lithium : ORM ActiveRecord PHP5 extrêmement léger
wamania est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/12/2007, 20h57   #13
Membre éprouvé
 
Avatar de Sayrus
 
Inscription : décembre 2005
Messages : 818
Détails du profil
Informations personnelles :
Âge : 27

Informations forums :
Inscription : décembre 2005
Messages : 818
Points : 456
Points : 456
Ok merci
Sayrus est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h19.


 
 
 
 
Partenaires

Hébergement Web