J'ai une requête hibernate qui est placée de manière dynamique en utilisant l'API de critères. Il génère des requêtes insuffisantes lentes, si elle est exécutée tel quel. P>
Mais j'ai noté qu'elles sont environ 1000% plus rapidement si je prépendisons / * + first_Rows (10) * / à la requête. Comment puis-je faire cela avec l'API de critère? P>
J'ai essayé des critères.SetComment (..), mais cela semble être ignoré. p>
dans les documents hibernate, 3.4.1.7. Les notes de requête sont mentionnées, mais cela indique clairement: "Notez que ce ne sont pas des indications de requête SQL" p>
Le résultat de la requête sera paginé, donc dans 99% des cas, je vais afficher les résultats 1-10. P>
4 Réponses :
Le problème est que la syntaxe d'indice n'est pas un commentaire, il ressemble à un peu comme un. Il doit vraiment aller entre le Au-delà de cela, il n'y a pas de balles d'argent. Mais, que vous le rebondissez jamais, si vous souhaitez utiliser la syntaxe d'indice d'oracle, vous devez descendre la route SQL native. P>
Que pouvez-vous faire d'autre? Je n'ai pas (encore) avoir beaucoup d'expérience de syntonisation hibernate. La seule fois que j'ai sous une telle tâche, la requête saisit des rangées de tout un tas de tables pour instancier un objet avec de nombreux sous-types. Chaque sous-type était une table séparée. La requête générée par Hibernate avait de nombreuses jointures extérieures, qui ont confondu le diable de l'optimiseur. Briser ce monstre dans plusieurs requêtes ciblées (une par sous-type) utilisée uniquement les jointures intérieures produisit une réduction de deux centaines de temps de récupération. p>
Cela peut ne pas être utile immédiatement pour vous. Mais le principe est, regardez la requête Hibernate et voyez si cela peut être mis en œuvre de manière différente et plus efficace. p> SELECT CODE> et les colonnes sélectionnées, tandis que
SETCOMMENT () CODE> Prepend le commentaire avant le code>. P>. P>.
first_rows code> n'est pas un outil d'amélioration de la performance. Cela peut finir par prendre plus de temps pour obtenir tous em> les rangées de retour. Bien sûr, dans un programme d'utilisation de l'utilisateur, la récupération des dix premières lignes peut être tout ce que nous devons faire. p>
Le résultat sera effectivement utilisé par l'utilisateur.
La requête elle-même est correcte comme c'est le cas. Comme il est généré de manière dynamique, il ne peut pas être optimisé manuellement, il est différent pour chaque requête de recherche.
Vous pouvez modifier le mode Optimizer au niveau de la session: soit juste avant votre requête, puis la replacez-la à sa valeur par défaut ( all_rows code>) ou Dans votre cas depuis 99% des requêtes en bénéficieraient, vous pouvez le modifier au niveau du schéma (avec un
sur la connexion code> déclencheur pour l'exemple) ou même au niveau de l'instance (modifier le paramètre init). p> p>
J'ai pu mettre dans un indice Oracle par un indice d'oracle en ajoutant une libération à la critère.
ProjectionList proList = Projections.projectionList(); proList.add(Projections.sqlProjection("/*+INDEX_DESC(this_ MY_INDEX_NAME)*/ 1 as MYHINT", new String[]{}, new Type[]{})); //add properties from your class proList.add(Projections.property("field1")); proList.add(Projections.property("field2")); proList.add(Projections.property("field3")); c.setProjection(proList);
J'ai une autre solution générique, qui devrait fonctionner pour chaque requête de critère:
Utilisez un commentaire standard et un intercepteur Hibernate modifiant le SQL ultime à la base de données.
(Je l'ai utilisé avec Hibernate 3.3, mais doit être utilisable pour chaque version, l'enregistrement de l'intercepteur peut être différent.)
Dans votre code de requête Utilisez: P>
<bean id="entityListener" class="your.package.HibernateEntityInterceptor"/> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="entityInterceptor" ref="entityListener"/> [...]