function based index - bogue
Salut, j'ai quelque chose à vous montrez. Je ne sais pas si c'est un bogue dans ma version d'oracle, mais bon.
Voici un select :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
SELECT D_RENVL,
C_TYPE_ASSR,
COUNT (C_TYPE_ASSR) TOTAL,
(SELECT COUNT (*)
FROM GENXXEF01.V_REMA002_POLICE P1
WHERE P1.C_TYPE_ASSR = P.C_TYPE_ASSR AND S_AGEN = 'C' AND (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) = P.D_RENVL)
TERMINE
FROM (SELECT (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) D_RENVL,
C_TYPE_ASSR,
N_TERM
FROM GENXXEF01.V_REMA002_POLICE
WHERE C_TYPE_ASSR IN ('HA', 'AU')) P
GROUP BY D_RENVL, C_TYPE_ASSR
ORDER BY D_RENVL DESC, C_TYPE_ASSR DESC |
ça fonctionne numéro 1. Pour améliorer la performance, j'ai décidé d'ajouter une function based index sur : (D_RENVL + (INTERVAL '1' YEAR) * N_TERM).
ça fonctionne encore numéro 1 mais encore plus rapide (< 1 seconde au lieu de plus de 30 secondes).
Maintenant j'ai un besoin de pagination, mais quand je fais ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
select * from (
SELECT D_RENVL,
C_TYPE_ASSR,
COUNT (C_TYPE_ASSR) TOTAL,
(SELECT COUNT (*)
FROM GENXXEF01.V_REMA002_POLICE P1
WHERE P1.C_TYPE_ASSR = P.C_TYPE_ASSR AND S_AGEN = 'C' AND (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) = P.D_RENVL)
TERMINE
FROM (SELECT (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) D_RENVL,
C_TYPE_ASSR,
N_TERM
FROM GENXXEF01.V_REMA002_POLICE
WHERE C_TYPE_ASSR IN ('HA', 'AU')) P
GROUP BY D_RENVL, C_TYPE_ASSR
ORDER BY D_RENVL DESC, C_TYPE_ASSR DESC) |
Ma colonne D_RENVL est maintenant blanche. Elle ne l'était pas sans le niveau supérieur de select. Je retire mon index et tout re-fonctionne à nouveau.
Je remet mon index et je fais quelques tests. Sans le ORDER by il n'y a pas de problème. Si je garde le order by mais que je fais TO_CHAR(D_RENVL,'YYYY-MM-DD') comme ci-dessous, là ça fonctionne!
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
select * from (
SELECT TO_CHAR(D_RENVL, 'YYYY-MM-DD'),
C_TYPE_ASSR,
COUNT (C_TYPE_ASSR) TOTAL,
(SELECT COUNT (*)
FROM GENXXEF01.V_REMA002_POLICE P1
WHERE P1.C_TYPE_ASSR = P.C_TYPE_ASSR AND S_AGEN = 'C' AND (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) = P.D_RENVL)
TERMINE
FROM (SELECT (D_RENVL + (INTERVAL '1' YEAR) * N_TERM) D_RENVL,
C_TYPE_ASSR,
N_TERM
FROM GENXXEF01.V_REMA002_POLICE
WHERE C_TYPE_ASSR IN ('HA', 'AU')) P
GROUP BY D_RENVL, C_TYPE_ASSR
ORDER BY D_RENVL DESC, C_TYPE_ASSR DESC) |
ça peut faire le travail le to_char, mais le dba en moi ne veut pas monter cet index en production sans comprendre le problème.
J'ai retiré le to_char et fais un autre test. Créer une table à partir du select qui est en problème. Oh my god...Ma session a plantée et j'ai eu un message :
ORA-7445 [evaopn3] generally occurs during the execution of a query.
The error typically only occurs with a specific stream of data being
fetched from the objects in the execution plan.
The problem is caused often by an optimization but it is not until a
row is fetched and evaluated that the error happens
Je ne comprends pas ce qui se passe. Pourtant la requête du millieu fonctionne super bien.
Ma version d'Oracle est 11.2.0.2.0.
Merci