Rechercher sur arkzoyd.com

27 février 2012

Oracle XMLType et DTD composées...

Les DTD sont, sans doute avec raison, considérées comme l'ancienne génération d'outil de description des documents XML, avantageusement remplaçables par les schémas XML (XSD) ou autres Relax NG.

Pourtant, la simplicité de leur écriture (et lecture), le non support des espaces de nommage (namespaces), leur antériorité et leur inclusion dans la norme, en font encore un outil très utilisé dans de nombreuses situations de mise en œuvre du XML.

Une DTD peut être inclue dans un document XML, référencer un fichier externe ou un peu des deux, c'est ce dernier exemple que trouverez dans cet article, mise en œuvre avec un XMLType et Oracle 11.2

22 février 2012

DBA_TABLES affiche-t-elle toutes les tables de votre base Oracle ?

Parfois, vous vous apercevez que ce que vous pensez depuis des années est faux ! Prenons le cas de DBA_TABLES, ALL_TABLES et USER_TABLES. Pensez-vous que ces vues affichent toutes les tables de la bases de données ? Et bien c'est loin d'être le cas, comme le montre le test ci-dessous :

17 février 2012

Arrêtez vos requêtes Oracle dans vos applications Java

Les formulaires de recherches multi-critères sont souvent une épine dans le pied des applications interactives. Je suis adepte de la solution brutale qui consiste à monter un cluster Hadoop et un formulaire avec une seul champ. Vous voyez de quoi je parle ?

Si vous n'avez pas 250 000 euros pour commencer ou l'ambition d'acheter un "BDA" [NDLR Oracle Big Data Appliance], cet article est peut-être pour vous ! Il présente un exemple d'utilisation de la méthode java.sql.ResultSet.setQueryTimeout pour arrêtez une requête qui n'a pas répondue au bout de X secondes depuis un formulaire multi-critères. Il revient sur l'affichage de "trop de données" aussi...

29 janvier 2012

Utilisation et limites d'Oracle 11g DBMS_XA

DBMS_XA permet plusieurs choses parmi lesquelles coordonner plusieurs branches d'une transaction globale dans des sessions différentes. Les exemples n'étant pas foison, ni sur le web, ni sur les sites d'Oracle pour décrire l'utilisation d'une transaction multi-sessions, cet article présente un cas simple qui utilise une seule et même instance...

Oracle permet alors d'accédez aux modifications non encore validées des autres sessions ; c'est parce que le branches de la transaction globale sont "tightly coupled".

Malheureusement, au moins en 11.2, ce fonctionnement se fait au prix d'une sérialisation des opérations des différentes sessions. Mauvais trip si vous pensiez vous en servir de cette fonctionnalité pour paralléliser vos traitements PL/SQL. Il faudra sans doute vous retourner vers des transactions globales déclenchées via les OCI ou une datasource native XA JDBC. Ce point est illustré à l'aide de 2 exemples ci-dessous. Mais assez parlez : à vos sessions SQL*Plus !

24 janvier 2012

Fonctions de table et Parallèlisme

Il y a quelques semaines, yooo13 qui se reconnaîtra ;-), rebondissant sur un problème de performance d'un des batchs sur lesquels je travaillais, pointait le fait que les fonctions de table ou fonctions "pipelined" peuvent être parallélisées et que j'y trouverais une solution à mon problème...

L'idée simple, et par ailleurs expliquée dans cet article, consiste à prendre le jeu de données d'origine et de le segmenter en jeux plus petits, à la "mapreduce"... Au final et dans mon cas, le résultat est excellent et permet, après 1/2 journée de travail, de diviser les temps de réponse par un facteur d'échelle, passant d'une heure à quelques minutes, par une manipulation purement technique.

Evidemment, ce n'est pas sans de quelques sacrifices. En particulier, l'introduction de code PL/SQL supplémentaire rend la solution, déjà mal écrite/décrite, encore plus difficile à comprendre et ce, malgré tous mes efforts. Mais le sujet de cet article est ailleurs, il s'agit d'illustrer, une des difficultés que j'ai rencontrée, travaillant sur un tout petit jeux de données de 1000 lignes pour équilibrer les "partitions" de mes exécutions en parallèle

22 janvier 2012

Un exemple d'utilisation du hint "CARDINALITY"

Le hint CARDINALITY permet d'aider l'optimiseur Oracle en lui "soufflant" le nombre de lignes retournées pour une étape d'un plan. Vous pensez qu'avec les différents mécanismes de dynamic sampling, cardinality feedback, statistiques multi-colonnes, statistiques sur les colonnes virtuelles et SQL Profile, ce hint est inutile ?

Voici une requête où typiquement, la seule solution, sauf de fixer le plan ou de réécrire le SQL, consiste à utiliser ce hint :

07 janvier 2012

Flashback et Snapshot Standby en Action

Qui utilise une base de données Oracle et n'a jamais besoin ?
  • d'investiguer les causes d'un problème constaté en production quelques minutes/heures auparavant
  • de tester une correction ou une évolutions et comparer le résultat à celui de la production
  • de ré-exécuter un batch après correction de données et réintégrer le résultat en production
  • de simuler des modifications pour des raisons techniques ou métier
Pour tous ces scénarios, une base de données standby est très utile et peut être ouverte en lecture-écriture... sans "Active Data Guard" mais simplement avec Flashback Logs et Snapshot Standby.

Cet article illustre comment combiner ces 2 fonctionnalités, faire reculer la base de données de standby et l'ouvrir en lecture écriture. Une fois vos tests réalisés, vous pourrez resynchroniser base de données primaire et standby...

04 janvier 2012

Le premier jour de la première semaine de 2012... à New-York !

Discussion lunaire fin 2011 à propos de la première semaine de 2012 : Google Calendar et Microsoft Outlook ne sont pas d'accord ! Il y a ceux qui pensent que la première semaine commence au premier lundi de l'année ; Et Outlook qui met le premier jour de l'année la première semaine... Si on s'en réfère à la description ISO des semaines, la première semaine de l'année est celle qui contient le premier jeudi de l'année.

Cette année, la première semaine commence donc le 2 comme le confirme le SQL ci-dessous qui utilise les formats de date d'Oracle :
select to_char(to_date('01/01/2012','DD/MM/YYYY'), 'IW/IYYY') SEM
  from dual;
SEM
-------
52/2011

select to_char(to_date('02/01/2012','DD/MM/YYYY'), 'IW/IYYY') SEM
  from dual;

SEM
-------
01/2012
Le 31 décembre 2012 est quant à lui la première semaine de 2013 :
select to_char(to_date('31/12/2012','DD/MM/YYYY'), 'IW/IYYY') SEM
  from dual;

SEM
-------
01/2013
Tout s'éclaire donc... Mais à vrai dire, ma préoccupation était moins le numéro de la semaine que la date du premier jour de la première semaine de l'année mais pas à Paris ! En France, le premier jour de la semaine est le lundi alors qu'aux Etats-Unis, c'est le dimanche :
alter session set nls_territory=FRANCE;

select to_char(to_date('01/01/2012','DD/MM/YYYY'), 'D') DAY
  from dual

D
-
7

alter session set nls_territory=AMERICA;

D
-
1
Question : "Quel est donc le premier jour de la première semaine de l'année au Etats-Unis ?". Demandons à Oracle...
alter session set nls_territory=AMERICA;
alter session set nls_date_format='DD/MM/YYYY';

select trunc(to_date('02/01/2012','DD/MM/YYYY'), 'IW') DAY
  from dual;

DAY
----------
02/01/2012
La réponse est donc un lundi... Même aux Etats-Unis ! Pourquoi ? Parce que dans la définition ISO des semaines, le premier jour de la semaine est le lundi. Seulement, voilà, j'ai beau chercher dans les formats de date d'Oracle, il n'y a pas de format qui permette de trouver le jour de la semaine ISO d'une date. 'D' dépend toujours du territoire. L'intérêt d'être en France est que 'D' signifie donc aussi le jour de la semaine ISO... Mais ce n'est pas vrai partout !

Et voilà, l'histoire de mon premier bug de 2012 qui est aussi le dernier de la dernière semaine de 2011... Bref, bonne année à tous !

24 décembre 2011

Développer des triggers "asynchrones" Oracle pour gagner en performance

Entre de mauvaises mains, les triggers sont des instruments de malheur. Leur temps d'exécution s'immisce dans les temps de réponse de vos ordres SQL sans que vous ne puissiez rien y faire...

Seulement, voilà, ré-écrire une application est extrêmement coûteux  et il faut trouver des moyens rapides de faire d'évoluer ses architectures pour améliorer l'expérience des utilisateurs sans sacrifice démesuré. Introduire de l'asynchronisme dans les codes de bases de données est une solution simple qui permet d'arriver à des résultats intéressants sans "tout casser"...

Le dessin ci-dessous illustre l'idée d'une telle transformation qui peut dans certain cas être redoutable : elle permet de lisser la charge, d'extraire le temps dédié aux triggers du temps de réponse et garantit malgré tout qu'il n'y a pas de perte d'information :

Cloner vos schémas Oracle avec la commande RMAN Transport Tablespace

A l'heure où les opérations sur vos bases de données doivent être simples, rapides et fiables, faire correspondre schéma(s) applicatif(s) et un jeu de tablespaces est un excellent moyen de gérer clone et migration, y compris d'une plateforme à l'autre.

Evidemment, cela suppose que votre application puisse utiliser comme paramètre le nom de son ou ses schémas. Cela suppose que le jeu de caractère soit suffisamment standard comme AL32UTF8. Cela suppose également que l'application ne s'appuie pas sur des objets partagés comme, par exemple, des privilèges, des synonymes ou des liens de bases de données avec des accès publics. Cela dit, même lorsque ces contraintes ne sont pas vérifiées, l'utilisation des tablespaces transportables peut s'avèrer d'une très grande utilité.

Cet article illustre comment cloner l'ensemble des tables et index du schéma DEMO dans la même base de données dans le schéma DEMO2. Il s'appuie pour cela sur le fait qu'il existe une correspondance entre l'utilisateur DEMO et un jeu de tablespace, en l'occurrence, ici, un seul tablespace. Il s'appuie sur la commande Tranport Tablespace de Recovery Manager. Le graphique ci-dessous illustre l'opération réalisée :