Bonjour,
Je cherche à optimiser une requête avec Jointure et j'aimerai avoir un avi.
La requête suivante s'exécute en 0.10 sec sur un jeu de données réduit, en revanche sur un jeu de données plus conséquent (2500000 LR_DESTINATION, 8000000 LR_DESTINATION_RUBRIQUE_GENRIQUE) le temp d'exécution dépasse bien souvent 1sec.
Objectif :
-1 Sélectionner l'ensemble des 'ID', depuis une table 'LR_DESTINATION',
dont l'ID de la 'LR_DESTINATION' est référencé dans la table 'LR_DESTINATION_RUBRIQUE_GENERIQUE' et dont les ID_RUBRIQUE appartiennent à l'ensemble (1,2,3,4,5,6,7).
-2 Ces 'ID' sélectionnés ne doivent pas être mémorisé au préalable, donc être absent de la table 'DESTINATION_MEMORY'
-3 Ces 'ID' sélectionnés seront ensuite filtrés sur leur URL et leur DONE.
Ma Requête :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 SELECT DISTINCT * FROM `LR_DESTINATION` LR LEFT JOIN DESTINATION_MEMORY DM ON DM.LR_DESTINATION_ID = LR.ID JOIN (SELECT DISTINCT LR_DESTINATION_ID FROM LR_DESTINATION_RUBRIQUE_GENERIQUE WHERE ID_GENERIQUE IN (20,21,22,23,24,25,26,27,28,29)) AS RUBJOIN ON RUBJOIN.LR_DESTINATION_ID = LR.ID WHERE DONE = 0 AND URL_SEO <> '/pros/url61234' AND ID_DEPARTEMENT = 'D090' AND DM.LR_DESTINATION_ID IS NULL LIMIT 0,25;
Ma Base de données
Table LR_DESTINATION
Table LR_DESTINATION_RUBRIQUE_GENERIQUE
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 CREATE TABLE `lr_destination` ( `ID` bigint(20) NOT NULL AUTO_INCREMENT, `URL_SEO` varchar(255) NOT NULL, `ID_LOCALITE` varchar(8) NOT NULL, `ID_DEPARTEMENT` varchar(4) NOT NULL, `ID_REGION` varchar(4) NOT NULL, `TITRE` varchar(255) NOT NULL, `NOMBRE_LIENS_MIS` int(11) NOT NULL, `NOMBRE_LIENS_MAX` int(11) NOT NULL, `DONE` tinyint(4) NOT NULL, PRIMARY KEY (`ID`), KEY `DONE` (`DONE`), KEY `URL_SEO` (`URL_SEO`), KEY `ID_DEPARTEMENT` (`ID_DEPARTEMENT`), KEY `ID_LOCALITE` (`ID_LOCALITE`), KEY `ID_REGION` (`ID_REGION`) ) ENGINE=InnoDB AUTO_INCREMENT=109109 DEFAULT CHARSET=latin1;
Table DESTINATION_MEMORY
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 CREATE TABLE `lr_destination_rubrique_generique` ( `LR_DESTINATION_ID` bigint(20) NOT NULL, `ID_GENERIQUE` int(8) NOT NULL, PRIMARY KEY (`LR_DESTINATION_ID`,`ID_GENERIQUE`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Explication:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 CREATE TABLE `destination_memory` ( `LR_DESTINATION_ID` int(11) NOT NULL, `TITRE` int(11) NOT NULL, `NOMBRE_LIENS_MIS` int(11) NOT NULL, `NOMBRE_LIENS_MAX` int(11) NOT NULL ) ENGINE=MEMORY DEFAULT CHARSET=latin1
- J'utilise un LEFT JOIN sur une table MEMORY pour éviter de faire un NOT IN (x,y,z)
- J'utilise un dans le JOIN un DISTINCT car plusieurs LR_DESTINATION_ID identiques peuvent remonter. Il s'agit d'une table de liaison entre des DESTINATIONS et des RUBRIQUES.
- Le DONE, URL_SEO, ID_DEPARTEMENT sont des discriminant de filtrage pour la sélection
Explain
On voit que la dernière requête effectue un FULL SCAN sur la table LR_DESTINATION_RUBRIQUE_GENERIQUE, 147821 correspondant exactement au nombre d'enregistrements dans cette table
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 +----+-------------+-----------------------------------+--------+-------------------------------------+---------+---------+---------------------------+--------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------------------------+--------+-------------------------------------+---------+---------+---------------------------+--------+--------------------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 54823 | Using temporary | | 1 | PRIMARY | LR | eq_ref | PRIMARY,DONE,URL_SEO,ID_DEPARTEMENT | PRIMARY | 8 | RUBJOIN.LR_DESTINATION_ID | 1 | Using where | | 1 | PRIMARY | DM | ALL | NULL | NULL | NULL | NULL | 25 | Using where; Not exists | | 2 | DERIVED | LR_DESTINATION_RUBRIQUE_GENERIQUE | index | NULL | PRIMARY | 12 | NULL | 147821 | Using where; Using index | +----+-------------+-----------------------------------+--------+-------------------------------------+---------+---------+---------------------------+--------+--------------------------+
Partager