Bonjour à tous,
Je voudrais améliorer le temps de traitement d'un de mes programmes qui utilise une base de données. Je benchmark plusieurs solutions en balançant la "charge" dans la requête SQL ou dans le langage de programmation qui est utilisé. Je teste également avec base de données non relationnelles (netcdf, hdf5). Je connais très bien le langage (Python) et beaucoup moins le SQL (j'utilise sqlite), du coup ma solution SQL est moins performante. J'attribue ceci en grande partie à ma "noobitude" en SQL et je voudrais voir avec vous ce que vous me conseillerez pour optimiser la requête qui fonctionne bien (= donne les bons résultats).
La base de données est très simple. J'ai des données climatiques (températures uniquement pour simplifier) prélevées en différents endroits de la planète (au sol). Et je vais avoir plusieurs mesures dans l'année.
Donc ça donne ceci en terme de tables:
localisations:
Id (integer, auto increment, primary key) Nom (text) Latitude (real) Longitude (real) 1 Trucmuche 20. 45. ... ... ... ...
mesures:
Id (integer, auto increment, primary key) Localisation (integer, foreign key => localisations) Date (date) Temperature (real) 1 1 01/01/2015 - 12:00:00 15.0 ... ... ... ...
L'objectif est de réaliser des statistiques sur les relevés de températures (dans une certaine période, dans une certaine zone géographique). Parmi toutes les mesures dont je dispose, il y en a qui m’intéressent tout particulièrement. J'ai une 3ème table pour gérer ces "favoris":
favoris:
Id (integer, auto increment, primary key) Localisation (integer, foreign key => localisations) 1 12 ... ...
Voici la requête que j'ai écrite pour extraire les températures mini et maxi sur toutes les localisations dans mes "favoris":
La 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
14
15
16 SELECT nom, max_temp, min_temp FROM localisations JOIN (SELECT mesures.localisation AS localisation, MAX(mesures.temperature) AS max_temp FROM mesures WHERE mesures.localisation IN (SELECT localisation FROM favoris) GROUP BY mesures.localisation) AS max_temps ON localisations.id = max_temps.localisation JOIN (SELECT mesures.localisation AS localisation, MIN(mesures.temperature) AS min_temp FROM mesures WHERE mesures.localisation IN (SELECT localisation FROM favoris) GROUP BY mesures.localisation) AS min_temps ON localisations.id = min_temps.localisation ORDER BY nom
est dupliquée. J'imagine que c'est pas très propre. Ensuite les jointures sont "lentes" avec les tables intermédiaires. Avec des tables qui sont dans la base, j'ai bien vu que les index améliorent très significativement la performance mais là je ne sais pas comment je pourrais indexer ni même si ce serait une bonne idée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part SELECT localisation FROM favoris
Si vous avez des idées ou des conseils, je suis preneur
P.S.: hdf5 (base de données hiérarchique) est performant sur ce genre de cas, il ne me convient pas tout à fait car j'ai besoin de l'aspect "relationnel" pour certaines requêtes (non exposées ici). Avant d'opter pour une solution hydride: une partie des données dans du hiérarchique pour faciliter le traitement statistique et la partie relationnelle dans une base de données relationnelle, je voudrais m'assurer que je n'arrive pas à de mauvaises conclusions du simple fait de mon inexpérience en SQL
Merci
Kango
Partager