Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
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 22/06/2011, 17h29   #1
Invité régulier
 
Homme
Etudiant Licence Bioinformatique
Inscription : juin 2011
Messages : 16
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Cantal (Auvergne)

Informations professionnelles :
Activité : Etudiant Licence Bioinformatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : juin 2011
Messages : 16
Points : 6
Points : 6
Par défaut Problème utilisation des index

Bonjour,

J'ai crée une base dont voici le code :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CREATE TABLE `base` (
  `Id` int(6) NOT NULL AUTO_INCREMENT,
  `Organisme` varchar(20) DEFAULT ' ' ',
  `Civilite` varchar(15) DEFAULT ' ' ,
  `Prenom` varchar(20) DEFAULT ' ',
  `Nom` varchar(31) DEFAULT ' ' COMMENT 'Nom de la personne',
  `Fonction1` varchar(30) DEFAULT ' ' COMMENT 'Fonction occupée',
  `Fonction2` varchar(30) DEFAULT ' ' COMMENT 'Fonction occupée',
  `Fonction3` varchar(30) DEFAULT ' ' COMMENT 'Fonction occupée',
  `Fonction4` varchar(30) DEFAULT ' ' COMMENT 'Fonction occupée',
  `Fonction5` varchar(30) DEFAULT ' ' COMMENT 'Fonction occupée',
  `Adresse` varchar(45) DEFAULT ' ' ,
  `CP` int(5) DEFAULT NULL,
  `Ville` varchar(35) DEFAULT ' ',
  `Telephone` varchar(15) DEFAULT ' ' ,
  `Portable` varchar(15) DEFAULT ' ' ,
  `E-Mail` varchar(50) DEFAULT ' ',
  `SiteInternet` varchar(45) DEFAULT ' ',
  `Territoire` varchar(13) DEFAULT ' ',
  PRIMARY KEY (`Id`),
  KEY `Territoire` (`Territoire`),
  KEY `Info` (`Organisme`,`Civilite`,`Prenom`,`Nom`,`Adresse`,`CP`,`Ville`,`Telephone`,`Portable`,`E-Mail`,`SiteInternet`),
  KEY `Fonction` (`Fonction1`,`Fonction2`,`Fonction3`,`Fonction4`,`Fonction5`)
) ENGINE=MyISAM  DEFAULT CHARSET=ascii AUTO_INCREMENT=331 ;
Voici quelque lignes insérées :
Code :
1
2
3
4
5
6
INSERT INTO `base` (`Id`, `Organisme`, `Civilite`, `Prenom`, `Nom`, `Fonction1`, `Fonction2`, `Fonction3`, `Fonction4`, `Fonction5`, `Adresse`, `CP`, `Ville`, `Telephone`, `Portable`, `E-Mail`, `SiteInternet`, `Territoire`) VALUES
(1, NULL, 'Monsieur', 'toto', 'toto', 'Agriculteurs', NULL, NULL, NULL, NULL, 'Chamb', 15000, 'LAVEIS', NULL, NULL, NULL, NULL, 'pm'),
(8, NULL, 'Monsieur', 'tata', 'tata', 'Conseiller municipal', NULL, 'Agriculteurs', NULL, NULL, 'Mons', 15000, 'VIRA', NULL, NULL, NULL, NULL, 'pm'),
(17, NULL, 'Monsieur', 'tutu', 'tutu', 'Conseiller municipal', NULL, NULL, 'Agriculteurs', NULL, 'Moled', 15300, 'LAVEISSEN', '05 99 73 99 89', NULL, NULL, NULL, 'pm'),
(24, NULL, 'Madame', 'titi', 'titi', 'Conseillere municipale', NULL, NULL, NULL, 'Agriculteurs', 'Secour', 15000, 'CEL', '05 99 73 99 89', NULL, NULL, NULL, 'pm'),
(154, NULL, 'Monsieur', 'tyty', 'tyty', 'Maire de Laviger', 'Agriculteurs', NULL, NULL, NULL, 'Buge', 15300, 'LAVIGER', '05 99 73 99 89', NULL, NULL, NULL, 'pm');
La ligne en gras indique que j'ai crée un index sur 5 colonnes (cf. 1er bloc de code; aperçu image jointe n°2)
D'après le cours sur le site ce n'est pas recommandé.
Admettons, je veux rechercher tous les agriculteurs, je suis obligé de comparer les valeurs des 5 colonnes à "Agriculteurs" car l'ordre de saisie peut changer.
Code :
1
2
3
SELECT *  
FROM `base` 
WHERE `Fonction1` LIKE 'a%' OR `Fonction2` LIKE 'a%' OR `Fonction3` LIKE 'a%' OR `Fonction4` LIKE 'a%' OR `Fonction5` LIKE 'a%'
Je voudrais savoir si en créant un (ou plusieurs) index je peux simplifier cette requête en faisant moins de 5 comparaisons.
Par exemple :
Code :
1
2
3
SELECT *  
FROM `base` 
WHERE `Fonction` LIKE 'a%'
/*Fonction fait référence à l'index crée sur les 5 colonnes fonctions*/
Remarque : Je sais que ma base ne respecte pas les normes, c'est volontaire donc je ne change pas la structure.
Remarque 2 : Un élus peut avoir plusieurs fonctions (ex : tata est conseiller municipal et agriculteurs)
La première image est un aperçu du résultat des 2 premiers bloc de code.
La seconde un aperçu des colonnes indéxées.
Le SGBD que j'utilise est MySQL.
J'espère avoir été assez clair sinon demander des informations supplémentaires.

Max
Images attachées
Type de fichier : jpg screenshot1.jpg (21,9 Ko, 4 affichages)
Type de fichier : jpg screenshot2.jpg (16,6 Ko, 4 affichages)
CCPMurat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 17h44   #2
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
Bonjour

la fonction des index n'est pas de "simplifier" les requêtes mais de les accélérer
En faisant un index sur plusieurs colonnes, cela ne crée pas une colonne synthétique

Je note ta remarque 1

par contre, ne connaissant pas MYSQL, je ne saurais dire si les index fonctionnent avec cette écriture

Citation:
WHERE `Fonction` LIKE 'a%'
????
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 21h10   #3
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Citation:
Remarque : Je sais que ma base ne respecte pas les normes, c'est volontaire donc je ne change pas la structure.
Et pourtant .. plus votre table va grossir et plus les performances des requêtes sur cette table vont devenir catastrophique.

La seule manière de "simplifier" votre requête actuelle est de passer par une re-modélisation de votre projet.

=> dégager les fonctions de cette table, faites une table de fonction et une table d'association.

Ensuite faites des jointures entre ces 3 tables et faites un jolie "fonction like 'a%'"
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 14h56   #4
Invité régulier
 
Homme
Etudiant Licence Bioinformatique
Inscription : juin 2011
Messages : 16
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Cantal (Auvergne)

Informations professionnelles :
Activité : Etudiant Licence Bioinformatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : juin 2011
Messages : 16
Points : 6
Points : 6
Créer une table "Elus" ET une table "FonctionO", jusque la pas de problèmes.
(cf image ci dessous)
Par contre pour la table d'association je ne vois pas ce qu'il faut mettre.

Remarque : La table FonctionO possède une seule colonne, je sais que ça ne correspond pas aux normes, c'est pour l'exemple.
CCPMurat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 15h05   #5
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
D'après votre exemple une personne peut avoir jusqu'à 5 fonctions différentes.

donc il vous faut bien une relation entre cette table de fonctions et votre table initiale

MCD :
personne 0,n---- Possède ----- 0,n Fonction

Lors du passage au MPD la relation Possède va se transformer en table.
Vous pouvez y rajouter par exemple une colonne de classement si c'est utile pour vous.

t_personne_prs (prs_id, ....)
R_prs_fun_pfu (prs_id, fun_id, ...)
t_fonction_fun (fun_id, fun_desc, ....)

Du coup, votre requête devient :
Code :
1
2
3
4
5
6
 
SELECT *
FROM t_personne_prs
INNER JOIN R_prs_fun_pfu ON pfu.prs_id = prs.prs_id
INNER JOIN t_fonction_fun fun ON fun.fun_id = pfu.fun_id
WHERE fun.fun_desc LIKE 'a%'
Le côté bénéfique :
votre LIKE se fera sur une table avec très peu de donnée (T_FONCTION_FUN) et vous évitera un scannage de table de T_PERSONNE_PRS comme vous l'avez surement actuellement.

Ensuite les jointures se font uniquement sur des pk => très rapide

Bref si vous pensez changer d'avis je vous conseillerais d'aller faire un tour sur le forum conception afin de retravailler proprement tout ceci
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/06/2011, 13h58   #6
Invité régulier
 
Homme
Etudiant Licence Bioinformatique
Inscription : juin 2011
Messages : 16
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Cantal (Auvergne)

Informations professionnelles :
Activité : Etudiant Licence Bioinformatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : juin 2011
Messages : 16
Points : 6
Points : 6
t_personne_prs (prs_id, ....) = elus(Id_e,...)
R_prs_fun_pfu (prs_id, fun_id, ...) = assoce(A_id_elus#,A_id_fonctiono#)
t_fonction_fun (fun_id, fun_desc, ....) = lsf(Numero,Fonction)
Donc ma requête doit être :
Code :
1
2
3
4
5
SELECT *, lsf.Fonction 
FROM elus, lsf 
INNER JOIN assoce ON assoce.A_id_elus = elus.Id_e
INNER JOIN lsf fon ON numero = assoce.A_id_Fonctiono
WHERE lsf.Fonction LIKE 'a%'
Or j'ai une erreur
Citation:
#1054 - Unknown column 'elus.Id_e' in 'on clause'
Pourquoi ?

Je suis sur du nom de la table et du nom de l'attribut. Id_e est lié à A_id_elus, ils sont de même type et de taille identique.
CCPMurat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/06/2011, 14h10   #7
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
Citation:
Envoyé par CCPMurat Voir le message
t_personne_prs (prs_id, ....) = elus(Id_e,...)
R_prs_fun_pfu (prs_id, fun_id, ...) = assoce(A_id_elus#,A_id_fonctiono#)
t_fonction_fun (fun_id, fun_desc, ....) = lsf(Numero,Fonction)
Donc ma requête doit être :
Code :
1
2
3
4
5
SELECT *, lsf.Fonction 
FROM elus, lsf 
INNER JOIN assoce ON assoce.A_id_elus = elus.Id_e
INNER JOIN lsf fon ON numero = assoce.A_id_Fonctiono
WHERE lsf.Fonction LIKE 'a%'
Or j'ai une erreur Pourquoi ?

Je suis sur du nom de la table et du nom de l'attribut. Id_e est lié à A_id_elus, ils sont de même type et de taille identique.
il y a un incohérence dans la requête. vous avez utilisé en MEME temps l'ancienne méthode "FROM elus, lsf " et la nouvelle (utilisant le INNER).
et une table a été oubliée !

Code :
1
2
3
4
SELECT *, lsf.Fonction 
FROM elus
   INNER JOIN assoce ON assoce.A_id_elus = elus.Id_e
   INNER JOIN lsf  ON lsf????.numero = assoce.A_id_Fonctiono
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/06/2011, 14h11   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
bonjour,

Déjà vous avez une jointure cartésienne en trop, et je pense que ça ne lui plait pas

Essayez comme ceci pour voir s'il y a encore une erreur ..
Code :
1
2
3
4
5
6
 
SELECT elu.*, fon.*
FROM elus elu
INNER JOIN assoce ass ON ass.A_id_elus = elu.Id_e
INNER JOIN lsf fon ON fon.numero = ass.A_id_Fonctiono
WHERE lsf.Fonction LIKE 'a%'
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2011, 11h32   #9
Invité régulier
 
Homme
Etudiant Licence Bioinformatique
Inscription : juin 2011
Messages : 16
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Cantal (Auvergne)

Informations professionnelles :
Activité : Etudiant Licence Bioinformatique
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : juin 2011
Messages : 16
Points : 6
Points : 6
J'ai trouvé une alternative à mon problème pour les index, elle est similaire à celle de punkoff et elle nécessite une requête avec plusieurs conditions mais ça résout mon problème.

Merci de vos réponse.
CCPMurat 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 05h43.


 
 
 
 
Partenaires

Hébergement Web