2009-12-15 10 views
0

J'ai une table avec plus de 10 000 000 lignes. En TOAD cette requête fonctionne très bien sur elle:NHibernate + Fluent Index NHibernate + Oracle

select /*+ INDEX(x IDX_CASHFLOW_COMPLEX)*/ * 
from MYPR.CASHFLOW x 
where fk_debet in (21856, 21854, 21855) 

IDX_CASHFLOW_COMPLEX est index sur 5 colonnes créé par le script suivant:

CREATE INDEX MYPR.IDX_CASHFLOW_COMPLEX ON MYPR.CASHFLOW 
(FK_DEBIT, FK_CREDIT, FK_DOCUMENT, PAYMENTDATE, FK_PAYMENTCODE) 
LOGGING 
TABLESPACE INDX 
PCTFREE 10 
INITRANS 2 
MAXTRANS 255 
STORAGE (
      INITIAL   64K 
      MINEXTENTS  1 
      MAXEXTENTS  UNLIMITED 
      PCTINCREASE  0 
      BUFFER_POOL  DEFAULT 
      ) 
NOPARALLEL; 

requête similaire mais sans syntaxe indice Oracle fonctionne beaucoup plus lent!

Pourriez-vous suggérer s'il est possible de dire à NHibernate d'ajouter un indice Oracle dans la requête?

Merci!

Répondre

0

Les statistiques de votre optimiseur sont-elles à jour? Sinon, vous pouvez constater qu'une fois qu'ils sont générés, vous n'avez pas besoin de l'indice du tout.

+0

Je vais vérifier que tommorow, merci pour la réponse – barser

0

Vraisemblablement, la requête sans l'indice n'utilise pas l'index.

Essayez ceci dans un outil sql:

explain plan for 
select /*+ INDEX(x IDX_CASHFLOW_COMPLEX)*/ * 
from MYPR.CASHFLOW x 
where fk_debet in (21856, 21854, 21855) 
/

select * from table(dbms_xplan.display) 
/

... et poster le résultat de la dernière commande. Nous pouvons l'utiliser pour voir quelles estimations fait l'oracle de la cardinalité attendue de l'ensemble de résultats.

+0

Je posterai le résultat ici demain matin du travail. Merci! En fait, je suis intéressant dans la possibilité d'ajouter des indications Oracle à toute requête nhibernate. Le cas que j'ai décrit au début est juste un exemple ... Ou ajouter des conseils à sql n'est pas une bonne pratique dans le monde des oracles? – barser

+0

Le plan expliqué a été publié comme autre réponse en raison du manque de formatage du code dans le champ de commentaire – barser

+0

Il semble que l'optimiseur pense que la table est minuscule, car elle évalue le coût d'un balayage de table complet à "2". La table a probablement des statistiques incorrectes et elles doivent être rassemblées à nouveau en utilisant DBMS_Stats. J'apprécie qu'un conseil dans la requête ferait l'affaire, mais vous devriez faire ceci pour presque chaque requête qui touche la table - beaucoup mieux pour obtenir les statistiques classées. –

0

Hint/* + INDEX (...) * /:

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------------- 
| Id | Operation | Name | Rows | Bytes | Cost | 
-------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT | | 1 | 238 | 26 | 
| 1 | INLIST ITERATOR | | | | | 
| 2 | TABLE ACCESS BY INDEX ROWID| CASHFLOW | 1 | 238 | 26 | 
|* 3 | INDEX RANGE SCAN | IDX_CASHFLOW_COMPLEX | 1 | | 2 | 
-------------------------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
3 - access("X"."FK_DEBIT"=21854 OR "X"."FK_DEBIT"=21855 OR "X"."FK_DEBIT"=21856) 
Note: cpu costing is off 

Sans indication/* + INDEX (...) * /:

------------------------------------------------------------------- 
| Id | Operation | Name | Rows | Bytes | Cost | 
-------------------------------------------------------------------- 
| 0 | SELECT STATEMENT | | 1 | 238 | 2 | 
|* 1 | TABLE ACCESS FULL | CASHFLOW | 1 | 238 | 2 | 
-------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
1 - filter("X"."FK_DEBIT"=21854 OR "X"."FK_DEBIT"=21855 OR "X" 
."FK_DEBIT"=21856) 
Note: cpu costing is off