dans Oracle, j'ai une table partitionnée. Les partitions sont de différentes tailles et ont une distribution de données différente. P>
J'aimerais avoir des instructions SQL d'émission hibernate qui inclut une valeur littérale pour la colonne de clés de partition plutôt qu'une variable de liaison. Il devrait utiliser des variables liées à toutes les autres valeurs bien sûr. P>
L'utilisation d'un littéral pour la clé de partition permettra à Oracle de proposer un plan spécifique à la partition connue et aux statistiques collectées. Cela pourrait également être utile pour les colonnes qui ont un histogramme en place pour des données asymétriques. P>
Il serait préférable de spécifier cela dans l'entité, sinon nous devrons le faire dans chaque requête. Existe-t-il un moyen de le faire dans Hibernate? P>
Nous sommes sur Hibernate 3.6.1 à l'aide du dialecte Oracle 10G. P>
S'il n'y a pas de moyen de le faire de manière native dans l'hibernate, puis-je créer un type d'utilisateur ou un dialecte ou quelque chose pour que cela se produise? P>
3 Réponses :
Non, les valeurs littérales ne sont pas prises en charge dans Hibernate. Je doute que si vous pouvez faire une solution de contournement, mais je suppose que vous recherchez une autre solution. P>
S'il n'y a absolument aucun moyen de le faire dans Hibernate, nous n'utiliserons pas hibernate.
En tant que solution de contournement, vous pouvez définir un commentaire unique sur chaque site d'appels "intéressant", de sorte que vous puissiez contrôler la variable de liaison de la variable d'oracle. de cette manière, l'optimiseur verra < code> "foo" code> au temps d'analyse durs (comme d'habitude). Dans les futures invocations, Oracle recherchera une copie exacte de la SQL pour réutiliser le plan d'exécution. Comme le commentaire rend la requête effectivement unique, cela vous donnera le même plan d'exécution calculé avec Vous devez faire attention car l'optimiseur utilisera également la valeur de "FOO" code>, et non d'une autre valeur de
param1 code>. P >
param2value code> pour calculer le plan d'exécution, de sorte qu'il pourrait interférer. Mais je pense que au moins cela vaut la peine d'essayer. P> p>
Nous avons désactivé une variable de liaison de liaison à cause de l'instabilité du plan qu'elle introduite. Un exemple a été un travail nocturne par lots - selon l'instance du client, l'instance du client a d'abord défini le plan pour ceux qui ont suivi. Ce n'était pas toujours bon.
Eh bien, c'est tout le point de cette solution de contournement: les requêtes qui devraient utiliser différents plans deviennent textuellement à Différents SQL, de sorte que vous ne devez pas désactiver les avantages et perdre ses avantages. Mais eh bien, vous n'allez pas le reconsurer pour cela.
Avez-vous pensé à utiliser des profils SQL pour les requêtes qui bénéficieraient du littéral?
Le problème de lutte contre la variable de liaison a été causé par une ancienne application. Un nouveau est en cours d'écriture en utilisant Hibernate. Je pense que nous serons obligés d'utiliser des "requêtes indigènes" hibernate où cette question et une cordon-concaténate dans les littéraux.
Vous pouvez utiliser la namedNativeQuery Voici un exemple de mise en œuvre.
La classe d'entité est p> et voici une implémentation DAO. P> public DataMartTransactionHistory findDataMartTransactionHistoryTR1(Long id) {
Query namedQuery = getSessionFactory().getCurrentSession().getNamedQuery("partitionTR1");
namedQuery.setLong(0, id);
return (DataMartTransactionHistory)namedQuery.list().get(0);
}
Au fait, ma table est aussi suivie. Créer une table DATAMARTTTRANSACTRISTORY (numéro d'identification (19) Non NULL, .... TRANSACTIONSTAtus Number (10)) Partition par liste (transactionStatus) (Partition TR1 Valeurs (1), Valeurs TR2 de partition (2))
Dans votre requête nommée, vous avez "où id =?". Êtes-vous en train de dire que cela sera remplacé par une valeur littérale plutôt qu'une variable de liaison?
Non, c'est une variable de liaison que j'ai ajoutée la "partition (TR1)" comme littéral. Vous pouvez ajouter plus ici. Si vous me donnez un, votre usecase spécifique, je peux vous générer un exemple spécifique.
Je vois, alors vous avez une requête nommée pour chaque partition?
Exactement, répond-il à vos besoins?
Type de. Pour le moment, il n'est pas nécessaire de changer de code Java lorsqu'une nouvelle partition est ajoutée. Cela ne semble pas être une meilleure approche que d'utiliser une interrogation native et une concaténation à la chaîne.
Le partage du curseur adaptatif de 11g souhaitait-il résoudre vos problèmes?
@JoneRes Oui, peut-être que 11g résoudront ces problèmes via le partage de curseur adaptatif et / ou le retour de cardinalité. Nous travaillons à la production de 11g à la production, mais il y a des tests considérables à faire là-bas.
Pour être clair, dis-tu que la partition élague elle-même fonctionne avec des variables liées, mais le plan de requête dans la partition (par exemple, la stratégie de jointure) n'est pas?
Dans notre configuration multi-locataires, les tables sont partitionnées par le locataire. Différents locataires ont des volumes différents et une déshibution des données en fonction des caractéristiques qu'ils utilisent et de leur entreprise. Oracle prend de meilleures décisions lors de l'utilisation des statistiques de niveau de partition que les statistiques de la table mondiale. La taille de la partition se produit à l'heure de toute façon.