Skip to main content.

Ordonnancement < Aspects généraux < Référentiel

Oracle

Oracle est un système de gestion de base de données relationnel (SGBDR) fourni par Oracle Corporation. Il a été développé par Larry Ellison, accompagné d’autres personnes telles que Bob Miner et Ed Oates.

Software Development Laboratories a été créé en 1977. En 1979, SDL change de nom en devenant Relational Software, Inc. (RSI) et introduit son produit Oracle V2 comme base de données relationnelle. La version 2 ne supportait pas les transactions mais implémentait les fonctionnalités SQL basiques de requête et jointure. Il n’y a jamais eu de version 1, pour des raisons de marketing, la première version a été la version 2. Celle-ci fonctionnait uniquement sur les systèmes Digital VAX/VMS.

- En 1983, RSI devient Oracle Corporation pour être plus représentative de son produit phare. La version 3 d’Oracle, entièrement ré-écrite en langage de programmation C, est publiée. Celle-ci supportait les transactions grâce aux fonctionnalités de commit et rollback. C’est aussi à partir de cette version que la plate-forme Unix est supportée.

- En 1984, la version 4 d’Oracle apparaît, supportant la cohérence en lecture (read consistency).

- Début 1985, Oracle commence à intégrer le modèle client-serveur, avec l’arrivée des réseaux au milieu des années 1980. La version 5 d’Oracle supporte donc les requêtes distribuées.

- En 1988, Oracle met sur le marché son ERP - Oracle Financials basé sur la base de données relationnelle Oracle. Oracle version 6 supporte le PL/SQL, le verrouillage de lignes (row-level locking) et les sauvegardes à chaud (hot backups, lorsque la base de données est ouverte).

- En 1992, la version 7 d’Oracle supporte les contraintes d’intégrité, les procédures stockées et les déclencheurs (triggers).

- En 1995, acquisition d’un puissant moteur multidimensionnel, commercialisé sous le nom d’Oracle Express.

- En 1997, la version 8 introduit le développement orienté objet et les applications multimédia.

- En 1999, la version 8i est publiée dans le but d’affiner ses applications avec Internet. La base de données comporte nativement une machine virtuelle Java.

- En 2001, Oracle 9i ajoute 400 nouvelles fonctionnalités et permet de lire et d’écrire des documents XML.

À partir de la version 9i, intégration du moteur OLAP au sein de Oracle : le moteur Oracle express est dorénavant référencé au sein de l’option Oracle OLAP. Les données multidimensionnelles sont accessibles à partir du langage SQL.

- En 2003, la version 10g est publiée. Le g signifie « grid » ; un des atouts marketing de la 10g est en effet qu’elle supporte le « grid computing ».

- En 2005, vers la fin novembre, une version complètement gratuite est publiée, la « Oracle Database 10g Express Edition ».

- Septembre 2009, sortie de Oracle 11g Release 2

Installation de la partie cliente sur Windows

La procédure la plus simple : L’installation des "Data Access Components".

Installation ODBC Oracle

Certains produits se connecte à la bae de données via l’interface ODBC.

Rubriques

Oracle Database Personal Edition

Version complète de la base de données pour un usage personnel qui est totalement compatible avec l’ensemble des produits de la gamme.


Base de données
Oracle
Voir aussi...
DB2, MS SQL, MSDE, PostGreSQL, Sybase, XBase

Dernières infos

Data Recovery Advisor n'est pas "RAC-Aware"

Si vous n'aviez pas encore lu cet article à propos d'Oracle 11g Data Recovery Advisor, c'est cet outil qui rend n'importe quel humain normal un DBA 11g exceptionnel puisque capable de restaurer une base de données. En effet, la combinaison des 3 commandes qui suivent LIST FAILURE, ADVISE FAILURE n puis REPAIR FAILURE génère et exécute les scripts RMAN les plus avancés allant jusqu'au Block Media Recovery. Et bien, merci ! RAC est toujours là pour me permettre de briller un peu, moi, le dinosaure qui considère toujours que connaître RMAN n'est pas un luxe !
Bonne surprise donc cet après midi donc puisque à la commande ADVISE FAILURE, le message suivant est apparut sous mes yeux incrédules sur un RAC 11.2 sur Solaris x86 :

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of advise command at 09/06/2010 16:10:08
RMAN-05533: ADVISE FAILURE is not supported on RAC database
Si vous n'y croyez pas, regardez la documentation RMAN à la commande ADVISE FAILURE. Si vous êtes fainéant, vous pouvez toujours passer votre base en single instance comme ceci :
sqlplus / as sysdba
alter system set cluster_database=false scope=spfile;
exit
srvctl config database
srvctl stop database -d x
sqlplus / as sysdba
startup;
Sinon et si vous voulez, par exemple, à tout prix éviter de "bouncer" votre base de données, faites comme moi, remettez-vous à RMAN ;-).

ArKZoYd
SQL Performance Analyzer et Virtual Private Database

Dans l'article précédent à propos des limites de SQL Performance Analyzer, j'ai souligné le fait que certaines informations comme la configuration NLS ou les informations de session n'étaient pas conservées lorsque vous ré-exécutiez les ordres capturés dans des SQL Tuning Set. Le résultat peut être que les différences constatées entre 2 exécutions ne viennent pas des changements réalisés comme la création d'un index ou le changement de version d'Oracle, mais de la méthode elle-même, y compris dans le cas de l'utilisation de SQL Performance Analyzer. Un autre exemple assez frappant est l'utilisation de la VPD comme vous allez le découvrir ci-après.

Le même exemple

L'exemple utilisé est identique à celui de l'article précédent :
  • Un schema demo
  • Une table T
  • Une requête marquée avec le commentaire MARKER
Après avoir créé et inséré les données dans la table et avant d'exécuter la requête, activez la VPD avec une fonction et une politique de "Row Level Security" comme celle créé dans le script ci-dessous :
connect / as sysdba

create or replace function maskall(object_schema    VARCHAR2,
                                   object_name      VARCHAR2)
  return varchar2 as
  retval varchar2(200);
begin
  if user='DEMO' then 
  retval:='2=1'; 
end if;
  return retval;
end;
/

BEGIN
  dbms_rls.add_policy(object_schema => 'demo',
     object_name     => 't',
     policy_name     => 'mask T',
     policy_function => 'maskall');
END;
/

Le résultat

Utilisez SQL Performance Analyzer et imprimez le rapport comme ci-dessous :

Comme vous pouvez le constater, la VPD n'est pas déclenchée dans le cas de SQLPA et cela même si on aurait aimé avoir le même résultat que lors de l'exécution initiale. Bien sur, vous vous dites pourquoi ne pas utiliser sys_context('userenv', 'current_schema') dans la fonction de la VPD ? La vérité est que la VPD n'est de toute façon pas déclenchée dans le cas d'utilisateurs comme SYS ou les utilisateurs ayant le privilege EXEMPT ACCESS POLICY.
Note: Pour les exceptions qui concernent la VPD, reportez-vous à la section suivante d'Oracle 11.2 Security Guide

Quelques limites d'Oracle SQL Performance Analyzer

Oracle Performance Analyzer est un outil fantastique de l'Option Real Application Testing. Il est apparu avec Oracle Database 11g. Pour l'avoir utilisé à plusieurs reprises dans des situations de migration, d'upgrade (il est possible collecter les informations originales sur une base 10g !) ou de changement d'infrastructure technique, il faut avouer que c'est une avancée majeure pour ce type de problématique. C'est aussi important que le moteur à réaction pour l'aviation ;-). Cela dit, si accrocher un réacteur à un avion n'est pas aussi simple qu'on peut l'entendre, réaliser une transformation d'un SI nécessite toujours, même avec des réacteurs, d'adresser certains points comme de :

  • comprendre le contexte et les enjeux,
  • fixer les objectifs,
  • gérer avec précision les configurations,
  • construire des sous-ensembles représentatifs qui soient représentatifs,
  • gérer les risques
N'oublions pas nos fondamentaux et ni pourquoi il faut encore des administrateurs... Cet article présente un exemple des limites que vous pourrez rencontrer avec DBMS_SQLPA lié au paramétrage NLS de votre client que celui-ci ne sait pas reproduire.

Schéma d'exemple

Pour les besoins de cette démonstration, je vais utiliser une paramètre de session qui est parfois utilisé en français pour retrouver des noms ou prénoms accentués NLS_COMP. Voici un script pour créer un schéma exemple et créer une requête que nous utiliserons avec SQL Performance Analyzer :
create user demo 
   identified by demo 
   default tablespace users 
   temporary tablespace temp;

grant connect, resource, dba to demo;

connect demo/demo

create table T(
  charkey varchar2(25 char) not null,
  text    varchar2(4000));

create index tidx on t(charkey);

insert into t
  values ('E', rpad('X',4000,'X'));
insert into t
  values ('é', rpad('X',4000,'X'));
insert into t
  values ('e', rpad('X',4000,'X'));
insert into t
  values ('F', rpad('X',4000,'X'));
insert into t
  values ('f', rpad('X',4000,'X'));

commit;

alter session set nls_language=french;
alter session set nls_territory=france;
alter session set nls_sort=french;
alter session set nls_comp=linguistic;

select /* MARKER */ charkey 
  from t 
 where charkey between 'E' and 'f'
 order by charkey;

CHARKEY
-------
E
e
é
F
f

SQL Tuning Set et SQL Performance Analyzer en action

Dans le script qui suit, vous allez capturer l'ordre SQL ainsi que l'ensemble des statistiques associées dans un SQL Tuning Set :
connect / as sysdba

col  sql_id format a20 new_value sql_id
select sql_id 
  from v$sql
 where regexp_like(sql_text, '[M]ARKER');

SQL_ID
---------------------------------------
dvxfphau4y4dx

prompt &&sql_id

begin
dbms_sqltune.drop_sqlset(
          sqlset_name=>'ArKZoYD');
end;
/

begin
dbms_sqltune.create_sqlset(
          sqlset_name=>'ArKZoYD',
          description=>'ArKZoYD SQL Tuning Set');
end;
/

DECLARE
l_cursor DBMS_SQLTUNE.sqlset_cursor;
BEGIN
OPEN l_cursor FOR
SELECT VALUE(p)
FROM TABLE (DBMS_SQLTUNE.select_cursor_cache (
                   'sql_id = ''&&sql_id''', -- basic_filter
                   NULL,                    -- object_filter
                   NULL,                    -- ranking_measure1
                   NULL,                    -- ranking_measure2
                   NULL,                    -- ranking_measure3
                   NULL,                    -- result_percentage
                   10)                      -- result_limit
          ) p;

DBMS_SQLTUNE.load_sqlset (
          sqlset_name => 'ArKZoYD',
          populate_cursor => l_cursor);
END;
/

select * from table(dbms_sqltune.SELECT_SQLSET(sqlset_name => 'ArKZoYD'));
Maintenant que l'ordre SQL est capturé, vous pouvez :
  • créer une tâche SQLPA,
  • enregistrer les statistiques et le plan du STS dans une première exécution du SQL PA,
  • demander au SQL PA de ré-exécuter l'ordre SQL collecté,
  • comparer les 2 exécutions (l'originale et la simulée)
var tname varchar2(100);
exec dbms_sqlpa.drop_analysis_task( -
           task_name   => 'SQLPArKZoYD');

exec :tname:=dbms_sqlpa.create_analysis_task( -
           sqlset_name => 'ArKZoYD', -
           task_name   => 'SQLPArKZoYD');

BEGIN
  DBMS_SQLPA.execute_analysis_task(
    task_name        => :tname,
    execution_type   => 'convert sqlset'
    );
END;
/

col task_name format a15
col execution_name format a15 new_value XNAME
col execution_type format a50

BEGIN
  DBMS_SQLPA.execute_analysis_task(
    task_name        => :tname,
    execution_type   => 'execute'
    );
END;
/

TASK_NAME EXECUTION_NAME EXECUTION_TYPE
--------------- --------------- --------------
SQLPArKZoYD EXEC_76  CONVERT SQLSET
SQLPArKZoYD EXEC_77  TEST EXECUTE

BEGIN
  DBMS_SQLPA.execute_analysis_task(
    task_name        => :tname,
    execution_type   => 'compare performance', 
    execution_params => dbms_advisor.arglist(
                          'execution_name1', 
                          'EXEC_76', 
                          'execution_name2', 
                          'EXEC_77')
    );
END;
/

select task_name, EXECUTION_NAME, EXECUTION_TYPE
  from USER_ADVISOR_EXECUTIONS
 where task_name='SQLPArKZoYD';

TASK_NAME EXECUTION_NAME EXECUTION_TYPE
--------------- --------------- --------------
SQLPArKZoYD EXEC_76  CONVERT SQLSET
SQLPArKZoYD EXEC_77  TEST EXECUTE
SQLPArKZoYD EXEC_78  COMPARE PERFORMANCE

var x clob
exec :x:=dbms_sqlpa.report_analysis_task(   -
           task_name => 'SQLPArKZoYD', -
           type=>'HTML',               -
           level => 'ALL',             -
           section => 'ALL',           -
           execution_name => 'EXEC_78');

set long 30000
set longchunksize 30000
set lines 30000
print x
Affichez le résultat en HTML. Voici une copie de la sortie correspondante :


Remarquez bien les découvertes de SQL Performance Analyzer; il s'agit de la même base de données, du même ordre SQL, du même contenu des tables. Pourtant, celui-ci vous annonce tranquillement :
  • les performances sont meilleures,
  • le plan d'exécution a changé,
  • le nombre de lignes ramenées est inférieur à l'exécution originale,

Conclusion

Vous l'aurez compris, les outils ne sont pas tout. La méthodologie est une autre clé. Ne vous trompez pas, mon propos n'est pas de dire que Real Application Testing n'est pas à la hauteur de ses promesses. Il est fantastique ! Gardez quand même la tête froide.
Pour en terminer avec cet exemple, supprimez le schéma demo, la tache SQLPA et le SQL Tuning Set :
connect / as sysdba

drop user demo cascade;

exec dbms_sqlpa.drop_analysis_task( -
           task_name   => 'SQLPArKZoYD');
exec dbms_sqltune.drop_sqlset( -
          sqlset_name=>'ArKZoYD');
Et notez, dans la même veine que :

  • SQL Performance Analyzer ne déclenche pas les triggers on-logon qui peuvent, par exemple, positionner des variables de session ou des catégories pour les outlines ou les profils SQL
  • SQL Performance Analyzer ne reproduit pas le contexte de session (ni les paramètres NLS dans ce cas, ni bien sur les variables)
  • Votre base de données (donc le SQL Tuning Set) ne collecte pas toutes les variables binds mais un maximum de 100 variables et seulement si celles-ci sont dans les clauses WHERE ou HAVING selon la documentation Oracle.

Oracle doit-il faire un tri après un INDEX FULL SCAN ?

Un index B*Tree étant organisé selon les valeurs des données, on peut imaginer que si un plan exécute une étape de type INDEX FULL SCAN sur un index, les données retournées par l'étape du plan en question sont triées. Si donc vous voulez ramener les données dans l'ordre des colonnes de l'index, une étape supplémentaire de tri est-elle bien utile ? Oui ? Non ? C'est la réponse à cette question haletante que vous découvrirez ci-dessous ! Plus sérieusement, ne vous êtes vous jamais demandé à quoi sert une étape particulière dans un plan ? Voici un exemple que vous avez déjà probablement rencontré 1000 fois; mais vous êtes vous posé la question ?

Les tests ci-dessous ont été réalisés sur une base 11.2.0.1 sur Linux 32 bits. Le comportenment peut varier sur d'autres versions

Pourquoi trier ce qui l'est déjà ?

Prenons un exemple simple d'une table avec 5 lignes et un index sur une colonne non nulle; pas de surprise, regardez le plan, si vous effectuer un ORDER BY dans le sens de l'index, les données étant déjà triées dans le plan, Oracle n'effectue le tri qu'une fois :
create table x (col1 number not null,
                col2 varchar2(4000));

insert into x values (1, rpad('X', 4000, 'X'));
insert into x values (2, rpad('X', 4000, 'X'));
insert into x values (3, rpad('X', 4000, 'X'));
insert into x values (4, rpad('X', 4000, 'X'));
insert into x values (5, rpad('X', 4000, 'X'));

commit;

exec dbms_stats.gather_table_stats(user, 'X')

create index xidx on x(col1);

select col1 from x order by 1;
select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
SQL_ID  c4zy2hvxux5v3, child number 0
-------------------------------------
select col1 from x order by 1

Plan hash value: 1230327558

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |       |     1 (100)|          |
|   1 |  INDEX FULL SCAN | XIDX |    10 |    30 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------
Si par contre, vous interrogez les données dans un ordre différent, surprise... Oracle ne fait toujours pas de tri après avoir fait un INDEX FULL SCAN mais change simplement son algorithme de parcours de l'index en INDEX FULL SCAN DESCENDING :
select col1 from x order by 1 desc;
select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
SQL_ID  bqwqbk6nta063, child number 0
-------------------------------------
select col1 from x order by 1 desc

Plan hash value: 91904716

-----------------------------------------------------------------------------------
| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |       |       |     1 (100)|          |
|   1 |  INDEX FULL SCAN DESCENDING| XIDX |    10 |    30 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Il n'y a toujours pas de tri.

Alors pourquoi Oracle fait-il un tri des données caractères?

Si vous changez le type des données de votre colonne indexée, le comportement est peut-être très différent (?); Oracle effectue peut-être un tri après avoir parcouru l'index comme c'est le cas sur mon système :
create table y (col1 varchar2(1 char) not null,
                col2 varchar2(4000));

insert into y values ('A', rpad('X', 4000, 'X'));
insert into y values ('B', rpad('X', 4000, 'X'));
insert into y values ('C', rpad('X', 4000, 'X'));
insert into y values ('D', rpad('X', 4000, 'X'));
insert into y values ('E', rpad('X', 4000, 'X'));

exec dbms_stats.gather_table_stats(user, 'Y')

create index yidx on y(col1);

select col1 from y order by 1;
select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
SQL_ID  6thd7cv3ha5jv, child number 1
-------------------------------------
select col1 from y order by 1

Plan hash value: 1664128530

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |       |     2 (100)|          |
|   1 |  SORT ORDER BY   |      |     5 |    10 |     2  (50)| 00:00:01 |
|   2 |   INDEX FULL SCAN| YIDX |     5 |    10 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------
Bon, l'explication est simple, et si vous obtenez un résultat différent, pas de panique, vous avez surement un client en anglais ou en américain. Ce plan est obtenu parce que mon client est en français et que NLS_SORT qui découle de la langue est également en français. Faite vos tris dans l'ordre binaire des caractères et vous verrez que l'étape de tri n'est plus exécutée :
alter session set nls_sort=binary;
select col1 from y order by 1;
select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
SQL_ID  6thd7cv3ha5jv, child number 2
-------------------------------------
select col1 from y order by 1

Plan hash value: 707317413

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |       |       |     1 (100)|          |
|   1 |  INDEX FULL SCAN | YIDX |     5 |    10 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------

Conclusion

Etre ordonné et parler français à un prix comme vous pouvez vous en rendre compte ci-dessus. Le résultat est que l'ordre des données ramenées dans une langue plutôt qu'une autre ou que dans l'ordre binaire est différent de l'ordre dans lequel les données sont indexées par Oracle dans un index classique :
truncate table y;

insert into y values ('e', rpad('X', 4000, 'X'));
insert into y values ('E', rpad('X', 4000, 'X'));
insert into y values ('é', rpad('X', 4000, 'X'));
insert into y values ('f', rpad('X', 4000, 'X'));
insert into y values ('F', rpad('X', 4000, 'X'));

commit;
exec dbms_stats.gather_table_stats(user, 'Y')

alter session set nls_sort=binary;
select col1 from y order by 1;

COL1
----
E
F
e
f
é

alter session set nls_sort=binary_ci;
select col1 from y order by 1;
COL1
----
e
E
F
f
é

alter session set nls_sort=french;
select col1 from y order by 1;
COL1
----
E
e
é
F
f
Bien sur, comme souvent, supprimez vous tables pour en terminer avec ce petit exemple:
drop table x purge;
drop table y purge;

Oracle Text et Data Mining (Partie 2)

Vous le savez, Oracle Data Mining (ODM) est un de mes sujets de prédilection. C'est notamment parce que le type d'informations qu'on arrive à extraire des données à partir des algorithmes spécialisés sont d'un intérêt extrême. Le décisionnel n'a alors plus rien à voir avec les explorations, même adhoc, des données réalisées par les utilisateurs. Dans les 2 parties de cet article, je montre comment utiliser Oracle Data Mining avec des documents non structurés. Pour cela, j'utilise le contenu de ce blog. L'article est découpé comme ceci :

  • La première partie de cet article publiée précédemment explique comment extraire les données depuis Internet et les charger en base de données ; c'est la plomberie !
  • Dans cette seconde partie, j'applique un algorithme de classification sans apprentissage (KMean) sur le texte de mes articles et je découvre avec stupéfaction la classification réalisée par ODM.
Vous noterez que la magie de cet exemple réside, entre autre, sur le fait que l'algorithme utilisé n'utilise aucune phase d'apprentissage. Si vous voulez aller plus loin dans la classification et influencer le moteur avec des classements déjà réalisées, vous utiliserez des algorithmes à apprentissage comme les arbres de décision ou les support vector machine (réseaux de neurones). Mais, sans allez jusque là, vous allez découvrir un résultat qui, j'en suis, sur vous étonnera...

Etape 1 : préparer les structures pour appliquer l'algorithme de clustering

Maintenant que nous avons les données dans la base de données, appliquer l'algorithme de classification est une formalité ! Il s'agit de créer un index Oracle Text; comme nous savons que nos articles sont en français, nous allons créer la structure d'index en français sans, toutefois, alimenter l'index :
exec ctx_ddl.create_preference('french_lexer','basic_lexer');
exec ctx_ddl.set_attribute('french_lexer','index_stems','french');
exec ctx_ddl.set_attribute('french_lexer','index_themes','yes');
exec ctx_ddl.set_attribute('french_lexer','theme_language','french');

create index article_idx 
    on article(TXT_CONTENT) 
       indextype is ctxsys.context 
       parameters('nopopulate lexer french_lexer');
Une fois l'index prêt, nous allons créer les tables qui stockerons les résultats de la classification et la description des clusters de données constitués :
create table restab (       
       docid NUMBER,
       clusterid NUMBER,
       score NUMBER);

create table clusters (
       clusterid NUMBER,
       descript varchar2(4000),
       label varchar2(200),
       sze   number,
       quality_score number,
       parent number);

Etape 2 : Exécuter l'algorithme

Une fois les structures préparée, il suffit de créer une préférence avec l'algorithme et ses paramètres; ici on utilise l'algorithme KMean et on créer 5 cluster de classifications :
exec ctx_ddl.create_preference('my_cluster','KMEAN_CLUSTERING');
exec ctx_ddl.set_attribute('my_cluster','CLUSTER_NUM','5')
Puis on exécute l'algorithme :
set timing on 
exec ctx_output.start_log('my_log');
exec ctx_cls.clustering('article_idx','id','restab','clusters','my_cluster');
exec ctx_output.end_log;
Après 6 secondes sont mon ordinateur portable, le résultat est constitué

Etape 3: Analyse de la classification

On peut désormais revoir le classement réalisé; les informations relatives au modèles sont dans la table clusters mais nous allons simplement visualiser le résultat dans la table restab comme si-dessous :
select CLUSTERID clu#, count(*) 
  from restab 
 group by CLUSTERID;

CLU# COUNT(*)
---- --------
   6       90
   4      123
   8      261
   7       53
   9      271
Regardons maintenant les articles les mieux classés dans le modèle généré à l'aide de la requête suivante qui ramène les articles dont le score est supérieur à 80% dans le classement :
col clusterid format 99 heading "CLU#"
col docid format 999 heading "ID"
col title format a90
col score format 9.99
set pages 1000
set lines 110
select r.CLUSTERID, r.DOCID, r.score, m.TITLE
  from restab r, metadata m
 where r.score>=0.8
   and m.id=r.DOCID
 order by r.CLUSTERID, m.PDATE
Le résultat est juste sidérant ; pour rappel, la base de données ne sait pas de quoi mon blog parle et je ne lui ai absolument rien appris comme j'aurais pu le faire avec un algorithme de réseau de neurones :
CLU#   ID SCORE TITLE
---- ---- ----- -----------------------------------------------------------------
   4   12   .91 /*+ oracle no:comments */ Colonnes corrélées et dynamic sampling
   4   94   .92 Exemple d'ordre SQL #1 /*+Anti-pattern*/
   4  101   .97 Exemple d'ordre SQL #2 /*+Anti-Pattern*/
   4   96   .99 Exemple d'ordre SQL #3 /*+Anti-Pattern*/
   4  105   .95 SQL #4 et SQL profile /*+Anti-Pattern*/
   4  104   .92 Exemple d'ordre SQL #5 et #6 /*+Anti-Pattern*/
   4   98   .91 Segment Advisor et SQL #7 /*+Premiers Pas*/
   4   97   .85 Surveiller l'utilisation des index et SQL #8
   4  115   .92 Statistiques d'un plan /*+ Need 4 Speed */
   4  111   .83 Créer un SQL Tuning Set (STS) /*+ Fast and Furious */
   4  106   .93 Index (ou presque)
   4  206   .96 Des temps de réponses plus rapides sans changer de plan !
   4  210   .98 Statistiques Multi-Colonnes en 11g
   4  195   .93 Statistiques et colonnes virtuelles en 11g
   4  208   .99 Bind Peeking et Variables Bind en 11g
   4  209   .87 Real Time SQL monitoring /*+ 11g Tuning Pack */
   4  175   .98 SQL Plan Management, la "killer app" de 11g
   4  194   .85 Real Application Testing (It's not RAC !) /*+ Part 2 */
   4  207   .89 Balade dans les "colonnes virtuelles" d'Oracle 11g
   4  202   .95 Les index invisibles de la 11g
   4  304   .97 "cursor_sharing=similar" et "method_opt=>'FOR ALL COLUMNS SIZE AUTO'"
   4  328   .93 Quand Consistent Gets n'est pas la meilleure façon de comparer des ordres SQL
   4  326   .87 Partitionner un index différemment de sa table
   4  334   .83 Pas plus de 2 lignes par bloc !
   4  339   .83 Estimer à quel point vos requêtes seront plus rapides avec Exadata Storage Server
   4  347   .95 11g et Correlations Multi-Colonnes sans statistiques étendues
   4  353   .91 Un Hint pour ignorer les Hints
   4  357   .98 Entre SQL Plan Management et SQL Profile (1/3)
   4  350   .98 Entre SQL Plan Management et SQL Profile (2/3)
   4  354   .97 Entre SQL Plan Management et SQL Profile (3/3)
   4  372   .97 L'Inquiétante ÿtrangeté d'Oracle Cost Based Optimizer
   4  375   .85 Afficher le résultat d'un "SELECT" verticalement.
   4  394   .85 Un UPDATE pas si bête...
   4  413   .96 V$SQL_BIND_CAPTURE, SQL Tuning Set (STS) et SQL Performance Analyzer (SPA)
   4  425   .82 Mon petit Data Mart (Partie 1) : Dimensions, Partitions et Données
   4  424   .81 Mon petit Data Mart (Partie 2) : Vues Matérialisées et Query Rewrite
   4  414   .84 Mon petit Data Mart (Partie 4) : Clés étrangÿres et Query Rewrite
   4  421   .87 Mon petit Data Mart (Partie 5) : Star Transformation et Bitmap Join Index
   4  420   .87 Oracle 11gR2 et un cas non documenté d'"Adaptive Cursor Sharing"
   4  435   .98 Changer un plan d'exécution avec Oracle 11g et DBMS_SPM
   4  450   .87 optimizer_dynamic_sampling=3+
   4  453   .95 Index B*Tree, INDEX FULL SCAN et fonctions dans une clause WHERE
   4  464   .95 Comparer le contenu de 2 SQL Tuning Set avec Oracle 11g R2
   6  227   .95 RMAN et Data Guard 11g (Part 1) : Active Database Duplication
   6  214   .87 RMAN et Data Guard 11g (Part 2) : Sauvegardes Multi-Sections
   6  259   .87 Installer/désinstaller 10g en ligne de commande
   6  257   .84 Installer/Désinstaller 11g en ligne de commande
   6  277   .86 Utiliser oraenv dans vos scripts
   6  287   .84 Cloner une base de données sans sauvegarde en 11g
   6  292   .84 Oracle 10.2.0.4, DBUA et Capture d'Activité sur 10g pour Database Replay
   6  285   .90 RMAN DUPLICATE à partir d'un BEGIN/END BACKUP
   6  306   .88 Database PITR et création/suppression de fichiers
   6  331   .92 Installer 11.1.0.7 (et les Patchs Set Suivants ?) en Silence
   6  343   .85 Cloner un ORACLE_HOME d'une base de données RAC 10g
   6  358   .83 Block Media Recovery et Data Recovery Advisor
   6  368   .91 La subtilité de RMAN contre la conviction de SQL*Plus
   7  199  1.00 Quand allez-vous mettre Oracle 11g en production ?
   7  249   .82 Une idée doit être exprimée de la maniÿre la plus simple possible
   7  317   .97 Séminaire Web : RAC 10g Tuning
   7  364  1.00 Pourquoi chanter réduit les perfomances des IO?
   7  402  1.00 APEX ou Excel ?
   7  410  1.00 Une pub Laposte.fr... ou est-ce une pub MacBook ou Starwars?
   7  462  1.00 Video "Exadata Flash Smart Cache" ou "Exadata & OLTP"
Maintenant considérez les thèmes suivants :
  • 4 -> Tuning SQL
  • 6 -> Installation et Sauvegardes
  • 7 -> Small Talk et Fun

Etape 4: Conclusion

Vous aurez, à n'en pas douter, compris l'intérêt d'utiliser Oracle Data Mining avec vos systèmes décisionnels ou simplement dans vos systèmes opérationnels. N'hésitez pas à partager vos remarques, vos expériences ou vos questions. Pour finir, supprimez les structures créées par ODM :
exec ctx_ddl.drop_preference('my_cluster');
drop index article_idx ;
drop table restab purge;
drop table clusters purge;
exec ctx_ddl.drop_preference('french_lexer');

A voir sur le net

Livres sur Oracle

Recherche de "oracle" de la Librairie Eyrolles.com

Oracle Database - Wikipédia

Article Wikipedia.