[Resolu] Requête SQL utra-looooongue...

Requête SQL utra-looooongue... [Resolu] - SQL/NoSQL - Programmation

Marsh Posté le 13-12-2009 à 12:24:03    

Bonjour à tous,
 
Je suis actuellement sur une requête SQL qui me pose problème: elle prend beaucoup trop de temps (entre 20 et 30min !!!)
Voici la structure de ma base de donnée:
 
http://img690.imageshack.us/img690/7226/bddiag.png
 
En SQL ça donne:
 

-- phpMyAdmin SQL Dump
-- version 3.2.0.1
 
--
-- Structure de la table `balises`
--
 
CREATE TABLE IF NOT EXISTS `balises` (
  `id` int(11) NOT NULL,
  `nom` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nom` (`nom`)
) ;
 
 
--
-- Structure de la table `documents`
--
 
CREATE TABLE IF NOT EXISTS `documents` (
  `nom` varchar(255) NOT NULL,
  `id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nom` (`nom`)
) ;
 
 
--
-- Structure de la table `mots`
--
 
CREATE TABLE IF NOT EXISTS `mots` (
  `id` int(11) NOT NULL,
  `mot` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ;
 
 
--
-- Structure de la table `noeuds`
--
 
CREATE TABLE IF NOT EXISTS `noeuds` (
  `id` int(11) NOT NULL,
  `pere` int(11) DEFAULT NULL,
  `document` int(11) NOT NULL,
  `balise` int(11) NOT NULL,
  `pre` int(11) NOT NULL,
  `post` int(11) NOT NULL,
  `index` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`pere`) REFERENCES `noeuds`(`id`),
  FOREIGN KEY (`document`) REFERENCES `documents`(`id`),
  FOREIGN KEY (`balise`) REFERENCES `balises`(`id`)
);
 
 
--
-- Structure de la table `references`
--
 
CREATE TABLE IF NOT EXISTS `references` (
  `noeud` int(11) NOT NULL,
  `mot` int(11) NOT NULL,
  `nbRef` int(11) NOT NULL,
  FOREIGN KEY (`mot`) REFERENCES `noeuds`(`id`),
  FOREIGN KEY (`noeud`) REFERENCES `noeuds`(`id`)
);
 


 
Je précise que le nombre d'enregistrements dans mes plus grosses table:
 - documents: 103
 - noeuds: 8 205
 - mots: 21 495
 - references: 200 982
 
et ma requête est:
 

SELECT DISTINCT documents.id
 , documents.nom
 , balises.id
 , balises.nom
 , noeudsall.id
 , noeudsall.pere
 , noeudsall.pre
 , noeudsall.post
 , noeudsall.`index`
FROM documents, balises, noeuds AS noeudsall, noeuds AS noeudsref, `references`, mots
WHERE ((mots.mot IN ( 'voyage', 'lourdes' ))
 AND (mots.id = `references`.mot)
 AND (`references`.noeud = noeudsref.id)
 AND (noeudsall.document = noeudsref.document)
 AND (noeudsall.pre <= noeudsref.pre)
 AND (noeudsall.post >= noeudsref.post)
 AND (noeudsall.document = documents.id)
 AND (noeudsall.balise = balises.id))
ORDER BY noeudsall.id, balises.id, documents.id


 
Quelqu'un pourrait-il me donner une piste ?
merci.


Message édité par ezeta le 13-12-2009 à 18:00:03

---------------
Mon topic d'achat / ventes
Reply

Marsh Posté le 13-12-2009 à 12:24:03   

Reply

Marsh Posté le 13-12-2009 à 13:57:06    

Première chose : écrire tes requêtes avec une syntaxe plus moderne, pour mettre en avant les jointures :

Code :
  1. SELECT DISTINCT documents.id
  2. , documents.nom
  3. , balises.id
  4. , balises.nom
  5. , noeudsall.id
  6. , noeudsall.pere
  7. , noeudsall.pre
  8. , noeudsall.post
  9. , noeudsall.`index`
  10. FROM documents
  11.          JOIN  noeuds AS noeudsall ON (noeudsall.document = documents.id)
  12.          JOIN  noeuds AS noeudsref ON (noeudsall.pre <= noeudsref.pre  AND noeudsall.document = noeudsref.document AND noeudsall.post >= noeudsref.post)
  13.          JOIN  `references` ON  (`references`.noeud = noeudsref.id)
  14.          JOIN mots ON  (mots.id = `references`.mot)
  15.          JOIN balises ON (noeudsall.balise = balises.id)
  16. WHERE mots.mot IN ( 'voyage', 'lourdes' )
  17. ORDER BY noeudsall.id, balises.id, documents.id
 

1ère piste : vérifier que tu as bien des indexes sur tes clés étrangères : references.mot, references.noeud, noeud.document, noeud.balise
2ème piste : s'il n'en manque pas / si le problème n'est pas résolu comme ça, fais un explain de ta requête pour voir où il peut y avoir un soucis...


Message édité par skeye le 13-12-2009 à 13:57:18

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 13-12-2009 à 15:30:01    

Bon, la première solution n'a rien apporté mis à part de la mise en page...
 
J'ai donc fait l'explain comme tu l'as dit, mais j'ai du mal à en interpréter le résultat :-/
 

id  select_type  table     type    possible_keys      key      key_len  ref                            rows    Extra
1     SIMPLE   references  ALL      mot,noeud         NULL     NULL     NULL                           200982  Using temporary; Using filesort
1     SIMPLE   noeudsref   eq_ref   PRIMARY,document  PRIMARY  4        ri_index.references.noeud      1    
1     SIMPLE   noeudsall   ref      document,balise   document 4        ri_index.noeudsref.document    13      Using where
1     SIMPLE   documents   eq_ref   PRIMARY           PRIMARY  4        ri_index.noeudsref.document    1    
1     SIMPLE   mots        eq_ref   PRIMARY           PRIMARY  4        ri_index.references.mot        1        Using where
1     SIMPLE   balises     eq_ref   PRIMARY           PRIMARY  4        ri_index.noeudsall.balise      1


---------------
Mon topic d'achat / ventes
Reply

Marsh Posté le 13-12-2009 à 16:22:09    

comme je pensais il fait un full scan sur ta table références...t'es sûr qu'il y a des index sur mot et noeud sur cette table?


Message édité par skeye le 13-12-2009 à 16:22:15

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 13-12-2009 à 17:59:26    

Ben je sais pas ce qui se passait, j'ai enlevé les indexs et je les ai remis et ça marche. :-)
 
merci les gens !


---------------
Mon topic d'achat / ventes
Reply

Marsh Posté le 14-12-2009 à 10:14:38    

index pas mis à jour. Ca arrive de temps en temps. :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed