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 28/04/2008, 16h30   #1
Membre du Club
 
Avatar de Dennis Nedry
 
Étudiant
Inscription : septembre 2007
Messages : 68
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : septembre 2007
Messages : 68
Points : 45
Points : 45
Par défaut Un DBMS_RANDOM pas si "random" que ça?

Bonjour.

je suis actuellement en train de tester un nouvel outil de Report, et je me suis attaqué à la partie "gestion des gros volumes de données".

Pour ce faire, j'utilise Oracle 10G Express edition.

J'ai, au préalable, créé 3 million de lignes sous excel, exportées dans Oracle via Access (qui mettait 20 minutes pour charger 1 malheureux million de lignes... )

Puis, j'ai démultiplié ces lignes sous Oracle, avec un code SQL tout simple:

Code :
1
2
3
4
 
INSERT INTO SALES(CLIENT_ID,EMPLOYEE_ID,YEAR,MONTH,SALES)
SELECT CLIENT_ID, DBMS_RANDOM.VALUE(150,179) AS EMPLOYEE_ID, YEAR+3 AS YEAR, MONTH, DBMS_RANDOM.VALUE(0,200)
FROM SALES;
DBMS_RANDOM sert à deux moments: pour générer le CA du client, et pour générer le numéro du commercial en charge du client.

Bref, en partant de 3 millions de lignes, j'ai démultiplié le tout pour arriver à 22,4 millions de lignes.

J'ouvre mon merveilleux outil de report, et, oh stupeur, que vois-je apparaître:



On observe que tous les commerciaux sont assez bien répartis, sauf 2 d'entre eux: les numéros 150 et 179, mes deux valeurs extrêmes.

Si on omet les 3 premières années (générées sous Excel, puis démultipliées sous Oracle pour gonfler les résultats), on remarque que les 2 valeurs extrèmes tombent exactement 50% de fois moins que les autres valeurs. Et chaque année correspond à environ 2 millions d'observations au total, donc le test est infaillible.

Est-ce normal? Sinon, comment y remédier?
Dennis Nedry est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 17h11   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Il me semble que les bornes ne sont jamais atteintes et que le dbms_random te renvoie un nombre à plusieurs décimales.

Donc c'est normal, vu que tu fais un Arrondi du nombre (implicite dans ton code).

Pour avoir 0, il faut que ça te renvoie de 0 à 0.499999
Pour avoir 1, il faut de 0.5 à 1.49999
...
Pour avoir 179, il faut de 178.50 à 179
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 17h13   #3
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Pour avoir de bonnes données, fais un trunc de ton résultat (avec max +1)

exemple
Code :
TRUNC(dbms_random.value(0, 180))
de 0 à 0.99999 => 0
de 1 à 1.99999 => 1
de 179 à 179.999999 => 179

Donc l'écart de chiffres est identique par code
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 17h44   #4
Membre du Club
 
Avatar de Dennis Nedry
 
Étudiant
Inscription : septembre 2007
Messages : 68
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : septembre 2007
Messages : 68
Points : 45
Points : 45
j'avais présent à l'esprit cette idée, mais je pensais que Oracle faisait déjà l'arrondi correctement... une peu comme un ALEA.ENTRE.BORNES() de Excel...

Bon, je teste vos conseils et je vous tiens au courant!
Dennis Nedry est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 17h46   #5
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Tiens nous au courant, c'est un bon sujet et avec tes 3M lignes c'est un super test.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 11h04   #6
Membre du Club
 
Avatar de Dennis Nedry
 
Étudiant
Inscription : septembre 2007
Messages : 68
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : septembre 2007
Messages : 68
Points : 45
Points : 45
C'est bon! tout fonctionne impeccablement.

la syntaxe à utiliser est donc:

Code :
1
2
3
INSERT INTO SALES(CLIENT_ID,EMPLOYEE_ID,YEAR,MONTH,SALES)
SELECT CLIENT_ID, TRUNC(dbms_random.value(150, 180)) AS EMPLOYEE_ID, YEAR+3 AS YEAR, MONTH, DBMS_RANDOM.VALUE(0,200)
FROM SALES;
Encore merci!

Citation:
Envoyé par McM Voir le message
Tiens nous au courant, c'est un bon sujet et avec tes 3M lignes c'est un super test.
Eh bien je vais te rassurer: je voulais faire un gros test de charge, donc j'ai pris la liberté de monter jusqu'à 90 millions de lignes . Je l'ai fait avant et après la correction du problême, comme ça on peut avoir une bonne base de test (et éventuellement, si quelqu'un pouvait l'ajouter aux FAQ, ce serait parfait!).


Sur un échantillon de 89 760 000 individus, En utilisant la fonction dbms_random.value(150, 179):



Les valeurs extrêmes sont sélectionnées 50% moins que les autres.

Et maintenant, avec TRUNC(dbms_random.value(150, 180))



la distribution est bien équirépartie.


En tout cas, un énorme
Dennis Nedry 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 19h59.


 
 
 
 
Partenaires

Hébergement Web