Question

Je suis en cours d'exécution des requêtes sur Oracle 10g avec JDBC (en utilisant les derniers pilotes et UCP comme DataSource) afin de récupérer CLOBs (moy. 20k caractères). Cependant, la performance semble être assez mauvaise: la récupération par lots de 100 LOB prend 4 s en moyenne. L'opération est également ni E / S ni CPU ni réseau lié à en juger d'après mes observations.

regarde la configuration de mon test comme ceci:

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

J'ai expérimenté avec les tailles mais sans aller chercher en vain. Est-ce que je fais quelque chose de mal? Yat-il un moyen d'accélérer la récupération CLOB lors de l'utilisation JDBC?

Était-ce utile?

La solution 4

Merci pour toutes les suggestions utiles. En dépit d'être signalée comme réponse au problème, ma réponse est qu'il semble y avoir aucune solution. J'ai essayé d'utiliser des déclarations parallèles, différentes caractéristiques de stockage, la température prétrié. tables et d'autres choses. L'opération ne semble pas être lié à une caractéristique visible à travers des traces ou expliquer les plans. Même le parallélisme des requêtes semble être peu précis quand CLOBs sont impliqués.

Sans doute il y aurait de meilleures options pour traiter avec de grandes CLOBs (en particulier compression) dans un environnement 11g mais atm. Je suis coincé avec 10g.

J'ai opté maintenant pour un aller-retour supplémentaire à la base de données dans laquelle je vais prétraiter les CLOB dans une taille optimisée RAW binaire. Dans les déploiements précédents cela a toujours été une option très rapide et sera probablement la peine de maintenir une ligne cache calculée. Le cache sera mise à jour et en utilisant réformé un processus persistant et AQ jusqu'à ce que quelqu'un arrive avec une meilleure idée.

Autres conseils

Mon expérience passée de l'utilisation des données de type Oracle LOB pour stocker de grandes données n'a pas été bonne. Il est très bien quand il est sous 4k car il stocker localement comme VARCHAR2. Une fois qu'il est terminé 4k, vous commencez à voir se dégrader la performance. Peut-être, les choses peuvent se sont améliorées depuis que je l'ai essayé il y a quelques années, mais voici les choses que je trouve dans le passé pour vos informations:

Comme les clients ont besoin pour obtenir LOB via le serveur Oracle, vous pouvez envisager la situation intéressante suivante.

  • données LOB concurrence limitée SGA cache avec un autre type de données si Oracle décider de le mettre en cache. Comme CLOB sont général grand, il peut donc pousser d'autres données
  • données LOB obtenez une mauvaise qualité de lecture du disque si oracle décide de ne pas mettre en cache, et diffuser les données au client.
  • fragmentation est probablement quelque chose que vous ne l'avez pas encore rencontré. Vous verrez si vos applications suppriment lobs et Oracle tente de réutiliser le lob. Je ne sais pas si le support oracle défragmenter le disque en ligne pour lob (ils ont des index, mais il faut beaucoup de temps lorsque nous avons essayé précédent).

Vous avez mentionné 4 s pour 100 lobs de 20k avg, il est donc 40ms par lobs. Rappelez-vous chaque lob doit avoir à récupérer via locater Lob séparé (ce n'est pas dans le jeu de résultats par défaut). C'est un voyage aller-retour supplémentaire pour chaque lob, je suppose (je ne suis pas sûr à 100% sur ce car il était tout à l'heure) Si tel est le cas, je suppose que ce sera au moins 5ms temps supplémentaire par voyage aller-retour pour série , droite? Si oui, votre performance est déjà limitée par la première lob séquentielle va chercher. Vous devriez être en mesure de vérifier en suivant le temps passé dans l'exécution sql vs fetching contenu lob. Vous pouvez le vérifier en excluant la colonne LOB comme le suggère la réponse précédente dans le poste, ce qui devrait vous dire si elle est liée lob.

Bonne chance

  

La taille totale de l'ensemble de résultats est dans les dix milliers - mesurée sur la durée de la récupération des coûts initiaux ensemble

Y at-il un ordre par la requête? 10K lignes est beaucoup si elle doit être triée.

En outre, la récupération du PK est pas un test équitable par rapport à la récupération de l'ensemble CLOB. Oracle stocke les lignes de la table avec probablement beaucoup dans un bloc, mais chacun des CLOBs (si elles sont> 4K) seront stockés hors de la ligne, chacun dans une série de blocs. Numérisation la liste des PK va donc être rapide. En outre, il y a probablement un index sur la PK, donc Oracle peut analyser rapidement les simplement blocs d'index et même pas accéder à la table.

4 secondes ne semble un peu élevé, mais il est 2MB qui doit être lu à partir du disque possible et transporté sur le réseau à votre programme Java. Réseau pourrait être un problème. Si vous effectuez une trace SQL de la session, il vous indiquera exactement où le temps est passé (disque lit ou réseau).

J'ai eu un problème similaire et a trouvé le JDBC lobs faire un appel réseau lorsque le accessin lobs.

de pilote JDBC Oracle 11,2 g vous pouvez utiliser un prefetch. Cet accès accéléré par 10 fois ...

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top