|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Membre confirmé
![]() Inscription : janvier 2006 Messages : 227 ![]() |
bonjour,
j'ai une table "table_1" de plus de 500.000 enregistrements et 150 champs (dont ident qui est la pk) j'ai transformé la table_1 en une table "table_2" comportant 3 colonnes ident,nom_champs,valeur: ident est l'ident de la table_1 nom_champs est l'un des 150 champs de la table table_1 valeur est la valeur d'un champs donné pour un ident donné par ex dans la table_1 ident champs1 champs2 .... champs150 id01 val1_1 val1_2 .... val1_150 id02 val2_1 ...... dans la table table_2 on aura ident nom_champs valeur id01 champs1 val1_1 id01 champs2 val1_2 ... id01 champs150 val1_150 id02 champs1 val2_1 ... j'ai rajouté sur table_2 2 index l'un sur ident l'autre sur nom_champs je réalise la requête sur la table_1 de la forme: la requête s’exécute en 3 sec sur la table_2 j’exécute la requête équivalente qui me donnera le même résultat Code :
SELECT sum(valeur) FROM table_2 WHERE nom_champs='champsn' je pensais q'un sgbd était optimisé pour des tables avec peu de colonnes même avec beaucoup d'enregistrements pourquoi observe t'on tant de différence? |
|
|
00
|
|
|
#2 | |
![]() ![]() Inscription : octobre 2008 Messages : 1 508 ![]() |
Citation:
Comparer les deux avec la fonction pg_total_relation_size() pour se faire une idée de la différence. Sur la requête citée, le cas où ça pourrait être gagnant serait pour les champs dont la valeurs serait vide la plupart du temps et non recopiées dans le nouveau modèle. Poste un EXPLAIN ANALYZE des 2 requêtes pour avoir éventuellement une analyse plus fine. |
|
|
|
00
|
|
|
#3 | ||||
|
Membre confirmé
![]() Inscription : janvier 2006 Messages : 227 ![]() |
bonsoir estofilo,
j'ai testé la fonction pg_total_relation_size, il n' y a pas photo de l'ordre de 1 à 13. mais même dans ce cas ,je n'ai pas une table monstrueusement grande,alors 120s pour une simple requete cela me parait enorme je te donne les 2 explain analyze pour la "table 3 colonnes" Code :
Code :
|
||||
|
|
00
|
|
|
#4 |
![]() ![]() Inscription : octobre 2008 Messages : 1 508 ![]() |
Il faudrait regarder ce que fait le système pendant ces 120s mais certainement qu'il attend le disque l'essentiel du temps. Le disque doit faire des accès non séquentiels, c'est ce qu'il y a de plus lent.
A partir de là il y a plusieurs pistes (en-dehors d'abandonner cette structure de données défavorable): 1) faire un CLUSTER de la table sur l'index varcod_t_donnees_fr1_idx. ca va réécrire toute la table en rangeant ensemble les données de même valeur par rapport à cet index OU/ET 2) augmenter considérablement random_page_cost (4.0 par défaut), moi je le monterai par incréments de 5 jusqu'à ce que l'optimiseur décide de changer de plan (ça devrait faire augmenter le coût du Bitmap Heap Scan). Mais dans tous les cas je présume que ça va rester loin des perfs de la requête 1. |
|
|
00
|
|
|
#5 |
|
Membre confirmé
![]() Inscription : janvier 2006 Messages : 227 ![]() |
bonsoir estofilo,
j'ai comme tu l'as suggéré fait un cluster sur l'index et là... ma requête se fait en 1 seconde ,plus rapide que la requête 1: je dis bravo si je fais un cluster sur un index portant sur deux champs ,est ce que cela peut être jouable? bonsoir et merci |
|
|
00
|
|
|
#6 |
![]() ![]() Inscription : octobre 2008 Messages : 1 508 ![]() |
Le CLUSTER porte forcément sur un seul index.
Il y a aussi un autre inconvénient à considérer, c'est qu'il faut le refaire régulièrement si le contenu de la table est souvent mis à jour. Pour les tables dans lesquelles on écrit rarement, c'est bien. Edit: l'index peut porter sur 2 champs, mais je ne sais pas si ça sert à quelque chose ici. |
|
|
00
|
|
|
#7 |
![]() ![]() Yoann MoreauIngénieur en laboratoire de recherche Inscription : septembre 2005 Messages : 724 ![]() |
Pour les requêtes où l'on veut lire toutes les valeurs d'une colonne (selon l'application dans sa globalité, pas juste pour un cas particulier). Il existe aussi des SGBD qui sont organisés par colonne et pas par ligne. C'est à dire que lire toutes les valeurs d'un champ sera plus rapide, mais lire tous les champs d'une ligne sera moins rapide.
Sinon comme l'a dit estofilo je pense qu'une table à 3 colonnes comme tu l'as fait n'est utile que s'il y a beaucoup de valeurs NULL. |
|
00
|
|
|
#8 | ||
![]() ![]() |
Ce genre de modélisation, on a été nombreux à l'essayer, et nombreux à vite s'en éloigner.
Appétissante de loin, des requêtes simples deviennent infernales à écrire. Écrivez la requête qui ramène l'ensemble des id, col1, col2, col3, col4, col5 qui répondent à ces critères : Col2 dans ('A', 'B', 'C') ET (Col3 = 4 OU Col5 = 5) Dans le premier cas, c'est simple : Code :
__________________
Email : http://scr.im/waldar |
||
|
00
|
|
|
#9 |
|
Membre confirmé
![]() Inscription : janvier 2006 Messages : 227 ![]() |
bonjour,
je crois en effet que je vais abandonné cette "solution", mais soyons positif cela m'a permis d’appréhender certains critères d'optimisation merci à tous et bonne journée |
|
|
00
|
|
|
#10 | ||||||
![]() ![]() |
Histoire de ne pas perdre ce que j'ai écrit voici le jeu de test que je m'étais construit :
Code :
Code :
Code :
Mais en effet à moins d'un besoin extrêmement spécifique il vaut mieux envisager de rester sur une modélisation classique. Je débute en PostgreSQL, sait-il gérer le partitionnement vertical ? Ça pourrait être une solution à votre problème.
__________________
Email : http://scr.im/waldar |
||||||
|
00
|
|
|
#11 | |||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 669 ![]() |
Citation:
En passant par un group by + having on peut s'en sortir avec moins de table scan, c'est à approfondir mais ... : Code :
|
|||
|
|
10
|
|
|
#12 |
![]() ![]() |
Très bien !
__________________
Email : http://scr.im/waldar |
|
00
|
|
|
#13 |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Le problème de PostGreSQL est double :
1) il ne sait pas faire des scans d'index 2) il n'implémente pas les vues indexées. Ces deux éléments auraient été plus qu’appréciable dans votre cas, car l'optimisation qui en résulterait serait au plus la lecture de quelques pages... A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
00
|
|
|
#14 | |
![]() ![]() Inscription : octobre 2008 Messages : 1 508 ![]() |
Citation:
Si ça se limite au SELECT sum(champn) FROM table_a_150_champs qui est trop lent, on peut très bien imaginer de maintenir une table à une seule ligne et 150 colonnes avec les SUM(champs_n) précalculés dans chaque colonne et mis à jour par trigger. L'accès en lecture serait instantané et le temps passé à mettre à jour cette table serait lissé sur tous les insert/update. Cette technique est efficace pour des fonctions simples comme SUM ou COUNT. Mais si les remarques ci-dessus portent sur la question plus générale du modèle EAV, d'abord postgres fait des scans d'index, donc le point 1) n'a pas lieu d'être, et sur le point 2) il faudrait déjà préciser ce que des vues peuvent apporter au problème, car on ne peut pas dire que ce soit notoirement évoqué dans les études de ce modèle. |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com