Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
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 19/01/2011, 10h19   #1
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
Par défaut Performance Int Vs VARCHAR Grosse table

Bonjour à tous,

j'ai une table "mesure" d'environ 20 million de lignes.

Et sur chaque mesure, j'ai un status qui peut être PASS, FAIL, ABORT ou rien.

Actuellement, le status est stocké dans un VARCHAR de 5 avec un index B-tree. Mais je pense pouvoir améliorer les performances.

J'ai ajouté un colonne à côté de type Number avec respectivement Pass=1, Fail=2, Abort=3, rien=0. J'ai vu que l'index avec null n'était pas très performant

J'ai fait quelques tests, et sur la plupart de mes requêtes avec un EXPLAIN, j'obtient un meilleur coût avec le numérique, ce qui semble à priori logique.

Y'avait-il un moyen de faire autrement avec le VARCHAR? J'avais pensé utilisé un Bitmap, mais la table a beaucoup d'insertion.
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h06   #2
Membre chevronné
 
Avatar de Z3phur
 
Homme loic
Administrateur de base de données
Inscription : décembre 2007
Messages : 673
Détails du profil
Informations personnelles :
Nom : Homme loic
Âge : 37
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : décembre 2007
Messages : 673
Points : 773
Points : 773
Bonjour,

oui avec le varchar2 tu pouvais tout simplement mettre "NULL" dans ta colonne à la place de rien.
__________________
==========================================
La justice sans la force est impuissante, la force sans la justice est tyrannique...
Z3phur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h13   #3
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Quelle est la distribution de vos données ?
Parce que vingt millions de lignes pour quatre valeurs, il y a surtout de grandes chances que l'index soit inutile.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h22   #4
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
La table contient des mesures de fréquence, et la colonne status indique si la fréquence calculé correspond à la norme lors du test.

Voici un exemple de distribution des mesures par status (j'ai pris la base de test)

STATUS COUNT(*)
------------------------
ABORT 10 599
FAIL 241 741
PASS 11 212 779
VIDE 306


Pourquoi sur Internet, je trouve que que NUMBER est similaire à VARCHAR d'un point de vue performance http://asktom.oracle.com/pls/apex/f?...98700346402356

Mon EXPLAIN m'indique pourtant bien un coût inférieur compris en 20 et 30%?

En fait, c'est une application développée il y a plus de 2 ans, la base a gonflé. Je cherche du coup à optimiser certaines requêtes ou à améliorer mon modèle de donnée.


Dans le même genre d'idée pour les clé primaire, j'ai une table de numéro de Série (Chaine sur 20 caractère).
Par habitude avec MySQL, j'ai créé une clé primaire NUMBER avec une séquence auto incrémente, et je fais mes jointures sur l'id au lieu de numéro de série.

Comment décider si l'utilisation d'un id qui ne veut rien dire fonctionnellement est mieux qu'un VARCHAR (Numéro de Série de mon produit) en clé primaire? Si j'utilisais mon Numéro de Série en clé unique, je pourrais par moment éviter les jointure. Pour info dans ce cas, l'index peut être rarement utilisé car j'utilise le like %search%.
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h52   #5
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 311
Points : 5 808
Points : 5 808
Le coût de l’Explain Plan n’est qu’une estimation plus ou moins fiable ; il dépend forcement des autres informations disponibles (statistiques à jours, etc.). Dans certaines cases la requête peut s’exécuter en réalité en prenant un tout autre chemin.
Pour optimiser vous vous prenez mal. Si vous avez un problème de performance identifiez d’abord le traitement concerné. Faite une analyse de ce qui se passe, collectez donc les informations nécessaire à la compréhension du problème. Vous avez besoin de savoir où intervenir et qu’est-ce que vous pouvez gagner à chaque solution.
Sinon les changements de type : remplacer chaîne de caractères par numérique, etc. sont une pure perte du temps.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h02   #6
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
Voici ma démarche qui ma amener à me poser cette question

J'avais quelques requêtes assez longues, j'ai donc fait un explain sur ces différentes requêtes et j'ai constaté entre autre que la plupart des requêtes devaient faire un full scan pour récupérer les lignes correspondant au critère status PASS.

Cette colonne de type VARCHAR2(5) ne contenait pas d'index, ce qui était la première erreur. Les performances ont été significativement amélioré dès que j'ai indexé la colonne.

Mais, pour aller plus loin, et prévoir le fait qu'elle va grossir encore. Je me demande si compte tenu du fait que la colonne ne prend que 4 valeurs (RIEN, PASS, FAIL ou ABORT), un numérique (0,1,2 ou 3) ne serait pas plus indiqué.



Pour le cas du numéro de série, c'est plus une conception d'ordre générale, je n'ai pas de problème de performance pour le moment. Toutefois, je constate que je fais régulièrement des jointures sur la table Numéro de Série en utilisant son id technique (clé primaire) du numéro de série. Alors que si j'utilisai le numéro de série (fonctionnel) en tant que tel comme clé primaire, je n'aurais pas à faire cette jointure.
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h09   #7
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Donc effectivement, la valeur PASS n'a pas grand intérêt à être indexée.
Vos requêtes portent essentiellement sur les autre valeurs ?

Un index bitmap fera l'affaire, ce n'est pas le nombre de lignes de la table qui compte, c'est le nombre de valeurs distinctes de la colonne. Ici elle est faible, l'index sera bon. Néanmoins les bitmap ont aussi leurs limitations.

Ce que dis le lien c'est que les nombres Oracle sont stockés comme les chaînes de caractères.

Néanmoins, stocker '0', '1', '2', '3' prend moins de place que 'ABORT', 'FAIL', 'PASS' ou null.

Pour votre autre question c'est un autre débat, clef naturelle ou clef de substitution :
http://asktom.oracle.com/pls/apex/f?...40000346704229
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h11   #8
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par ttropardy Voir le message
j'ai constaté entre autre que la plupart des requêtes devaient faire un full scan pour récupérer les lignes correspondant au critère status PASS.

Cette colonne de type VARCHAR2(5) ne contenait pas d'index, ce qui était la première erreur. Les performances ont été significativement amélioré dès que j'ai indexé la colonne.
Non sur les critères PASS, Oracle n'utilisera pas votre index et continuera les full scan.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h15   #9
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
J'ai vu qu'un index bitmap était très pertinent pour un nombre de valeur distinct très faible, ce qui correspond bien à mon besoin avec mes 4 statuts.

Mais qu'il avait l'inconvénient de devoir être reconstruit à chaque insertion. Dans mon cas, j'ai des insertions régulière.

Après avoir mis l'index (type B-Tree), le EXPLAIN m'a indiquer qu'il utilisait mon index que je venais de créer. Et la requête en elle-même a perdu quelques secondes à l’exécution.

Pourquoi ne serait-il pas utiliser sur une requête avec le critère WHERE status='PASS'
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h26   #10
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Parce pour la baleur PASS, Oracle doit lire 11212779 fois l'index puis lire 11212779 fois la table, qio est plus lent que de lire 11465425 fois la table.

Au contraire pour la valeur ABORT, lire 10599 fois l'index puis 10599 fois la table sera beaucoup plus rapide que de lire 11465425 fois la table.

Si vos statistiques sont à jour, l'optimiseur Oracle en tiendra compte.

En environnement OLTP, effectivement vous pouvez oublier les bitmap.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h35   #11
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
Donc, pour résumer

Je suis mieux pour le moment de laisser mon statut en varchar2(5)

Vu que les tests m'ont montré que la requête avec l'index semble quand même plus rapide, je pense que je vais garder l'index.

Si un bitmap est compatible avec un grand nombre d'insertion, ça me parait effectivement le plus adapté à mon cas

Merci beaucoup.
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 12h55   #12
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Si une recherche sur statut is null est fréquente, il faut "indéxer les null", pour éviter un full scan.
Donc créer un index sur (status,0) par exemple ou même peut être créer un Function Based Index du type :
Code :
CREATE INDEX idx_statut_null ON t (case when statut IS NULL then 1 end);
Mais ça implique que modifier la clause where des requêtes en :
Code :
WHERE (case when statut IS NULL then 1 end) = 1
L'avantage de l'index sur case est d'avoir un index tout petit (300 lignes au lieu de 20M) donc encore plus performant pour la recherche sur les nulls.

La manip la plus simple est de créer l'index sur (statut,0), pas de modification de code et livraison en prod avec un minimum d'indispo (comparé à la création d'une nouvelle colonne)
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 18h34   #13
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 311
Points : 5 808
Points : 5 808
Comme Waldar vous l'a indiqué l'index sur la colonne en question ne présent d'intérêt que pour certains requêtes. Donc ce sont vos requêtes qui indique si l'index est pertinent ou pas.

Si vous avez ciblé le traitement qui doit être optimisé vous devez analyser ce traitement dans son ensemble et non pas requête par requête.
Traitement optimisé != Somme des requêtes optimisées
c'est à dire que vous pouvez avoir N requêtes optimales dans un traitement sous-optimal.

A propos vos requêtes utilise-t-elles des variables de liaison ou pas? Si c'est le cas vous pouvez encore avoir des mauvaise surprises avec votre index. Avez-vous faite une trace sql du traitement ou pas ?
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 20h24   #14
Membre Expert
 
Avatar de pachot
 
Homme Franck Pachot
DBA Oracle
Inscription : novembre 2007
Messages : 703
Détails du profil
Informations personnelles :
Nom : Homme Franck Pachot
Âge : 41
Localisation : Suisse

Informations professionnelles :
Activité : DBA Oracle
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2007
Messages : 703
Points : 1 630
Points : 1 630
Bonjour

Citation:
J'ai fait quelques tests, et sur la plupart de mes requêtes avec un EXPLAIN, j'obtient un meilleur coût avec le numérique, ce qui semble à priori logique.
Il n'y a pas de raison pour que le traitement d'un number soit plus rapide que celui d'un varchar.
Mais évidemment, 'PASS' fait 4 octets (voire plus suivant le characterset) alors que 1 ne prends que 2 octets. Ce serait 'P' ce serait différent.

En voyant les requêtes avec leur plan d'exécution, ce serait probablement facile à expliquer.

Cordialement,
Franck.
__________________
A lire sur mon blog Oracle - Articles d'Experts des articles traduits en français de Jonathan Lewis, Tom Kyte, Doug Burns, Cary Millsap, Greg Rahn ...
pachot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 22h39   #15
Membre confirmé
 
Avatar de Ahmed AANGOUR
 
Homme Ahmed AANGOUR
DBA Etudes Oracle
Inscription : janvier 2010
Messages : 123
Détails du profil
Informations personnelles :
Nom : Homme Ahmed AANGOUR
Âge : 33
Localisation : France

Informations professionnelles :
Activité : DBA Etudes Oracle

Informations forums :
Inscription : janvier 2010
Messages : 123
Points : 217
Points : 217
Comme l'a fait remarqué Franck, sans plans d'exécution et j'ajouterai même sans statistiques d'exécutions il est difficile de donner un avis.

Par rapport à ce qu'a dit Waldar j'ajouterai qu'avoir des stats à jour ne suffit pas: vu que la colonne est skewed il faudrait calculer des histogrammes pour cette colonne afin que le CBO puisse estimer la bonne cardinalité.

cdmt,
Ahmed
__________________
Mon blog Oracle: http://ahmedaangour.blogspot.com/
Ahmed AANGOUR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2011, 11h04   #16
Nouveau Membre du Club
 
Thibaut
Inscription : février 2008
Messages : 115
Détails du profil
Informations personnelles :
Nom : Thibaut

Informations forums :
Inscription : février 2008
Messages : 115
Points : 39
Points : 39
Sur les 3 requêtes qui utilisent le statut, je constate une amélioration des performances avec un index bitmap, la base n'est plus susceptible d'évoluer en terme d'espace, donc cette solution me convient.

Juste pour savoir, quel est la requête pour remettre à jour les statistiques?
w3blogfr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2011, 11h06   #17
Membre chevronné
 
Avatar de Z3phur
 
Homme loic
Administrateur de base de données
Inscription : décembre 2007
Messages : 673
Détails du profil
Informations personnelles :
Nom : Homme loic
Âge : 37
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Industrie

Informations forums :
Inscription : décembre 2007
Messages : 673
Points : 773
Points : 773
Bonjour,

http://www.oracle-base.com/articles/...Statistics.php
__________________
==========================================
La justice sans la force est impuissante, la force sans la justice est tyrannique...
Z3phur 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 01h13.


 
 
 
 
Partenaires

Hébergement Web