Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/09/2011, 15h41   #1
Membre du Club
 
Avatar de skulled
 
Inscription : décembre 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 90
Points : 54
Points : 54
Par défaut Créer un index sur un trunc date

Bonjour,

Je souhaiterais savoir si il est possible de créer un index sur le champs "Date" d'une table mais précisément sur le "trunc(CHAMP_DATE) ".
Car mes requetes sont souvent portées sur le trunc de la date.

Exemple :
Code :
SELECT * FROM CLIENT WHERE trunc(CLIENT_DATE) <= trunc(sysdate-1)
Merci
skulled est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 15h50   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
Code :
CREATE INDEX client_date ON CLIENT (TRUNC(CLIENT_DATE))
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/09/2011, 15h54   #3
Membre confirmé
 
Homme Grégoire MARTIN
Ingénieur développement logiciels
Inscription : janvier 2011
Messages : 128
Détails du profil
Informations personnelles :
Nom : Homme Grégoire MARTIN
Âge : 32
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Finance

Informations forums :
Inscription : janvier 2011
Messages : 128
Points : 225
Points : 225
Bonjour,

Oui c'est possible


Code :
CREATE INDEX INDX_CLIENT_xx ON CLIENT (TRUNC(CLIENT_DATE));
Puis n’oublie pas de calculer les stats après :

Code :
1
2
3
4
5
6
7
8
9
 
BEGIN
    DBMS_STATS.gather_table_stats(tabname => 'CLIENT'
            ,ownname => <le owner de ta table>
            ,cascade => TRUE
            ,estimate_percent => 25
    );
end;
/
__________________
Cordialement.
ORA-007 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 20/09/2011, 16h21   #4
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Citation:
Envoyé par ORA-007 Voir le message
Puis n'oubli pas de calculer les stats apres :

Code :
1
2
3
4
5
6
7
8
9
 
BEGIN
    DBMS_STATS.gather_table_stats(tabname => 'CLIENT'
            ,ownname => <le owner de ta table>
            ,cascade => TRUE
            ,estimate_percent => 25
    );
end;
/
Certainement, mais comme vous le savez peut-être, un index de ce type est caractérisé par une colonne cachée et donc il va falloir bien faire attention à ce que le CBO connaisse les statistiques sur cette colonne cachée

Code :
1
2
3
4
5
6
7
BEGIN
dbms_stats.gather_table_stats(ownname=> user
                                        , tabname=> 'T'
                                       , estimate_percent=>null
                                        , cascade=>true
                                        , method_opt=> 'FOR ALL HIDDEN COLUMNS SIZE 1');
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 16h24   #5
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Citation:
Envoyé par McM Voir le message
Code :
CREATE INDEX client_date ON CLIENT (TRUNC(CLIENT_DATE))
Et n'oubliez pas une chose aussi:

Pour que votre requête puisse bénéficier de ce nouvel index il faut que la clause where coincide parfaitement avec la définition de cet index

Code :
1
2
3
4
 
SELECT a, b,c
FROM t
WHERE trunc(client_date) = to_date('20092011','ddmmrrrrr');
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/09/2011, 16h30   #6
Membre du Club
 
Avatar de skulled
 
Inscription : décembre 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 90
Points : 54
Points : 54
Merci à tous ça fonctionne, j'ai testé en lançant un plan d'éxecution et je vois bien que l'index est utilisé


Citation:
Envoyé par Mohamed.Houri Voir le message
Et n'oubliez pas une chose aussi:

Pour que votre requête puisse bénéficier de ce nouvel index il faut que la clause where coincide parfaitement avec la définition de cet index

Code :
1
2
3
4
 
SELECT a, b,c
FROM t
WHERE trunc(client_date) = to_date('20092011','ddmmrrrrr');
Merci pour l'info!
skulled est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 17h59   #7
Membre confirmé
 
Homme Grégoire MARTIN
Ingénieur développement logiciels
Inscription : janvier 2011
Messages : 128
Détails du profil
Informations personnelles :
Nom : Homme Grégoire MARTIN
Âge : 32
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Finance

Informations forums :
Inscription : janvier 2011
Messages : 128
Points : 225
Points : 225
Citation:
Envoyé par Mohamed.Houri Voir le message
Certainement, mais comme vous le savez peut-être, un index de ce type est caractérisé par une colonne cachée et donc il va falloir bien faire attention à ce que le CBO connaisse les statistiques sur cette colonne cachée
Alors il me semble que par defaut il le fait :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CREATE TABLE TEST_GREG (
ID_TEST NUMBER,
CHAMP1  VARCHAR2(50),
CHAMP2  VARCHAR2(50),
CHAMP3  VARCHAR2(50),
CHAMP4  VARCHAR2(50)
);
 
 
INSERT INTO TEST_GREG
VALUES (1,'A','A','A','A');
INSERT INTO TEST_GREG
VALUES (2,'A','A','A','B');
INSERT INTO TEST_GREG
VALUES (3,'A','A','B','B');
INSERT INTO TEST_GREG
VALUES (4,'A','B','B','B');
INSERT INTO TEST_GREG
VALUES (5,'A','B','B','B');
 
COMMIT;
 
CREATE INDEX INDX_TEST_GREG_01 ON TEST_GREG(UPPER(champ1));
 
SELECT column_name, num_distinct, hidden_column, virtual_column 
FROM all_tab_cols
WHERE table_name='TEST_GREG';
Donne :
Code :
1
2
3
4
5
6
7
8
 
   	COLUMN_NAME	NUM_DISTINCT	HIDDEN_COLUMN	VIRTUAL_COLUMN
	ID_TEST		                                       NO	          NO
	CHAMP1		                                       NO	          NO
	CHAMP2		                                       NO	          NO
	CHAMP3		                                       NO	          NO
	CHAMP4		                                       NO	          NO
	SYS_NC00006$		                               YES	          YES
Puis :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
BEGIN
    DBMS_STATS.gather_table_stats(tabname => 'TEST_GREG'
            ,ownname => 'TRANSCO'
            ,cascade => TRUE
            ,estimate_percent => 25
    );
end;
/
 
SELECT column_name, num_distinct, hidden_column, virtual_column 
FROM all_tab_cols
WHERE table_name='TEST_GREG';
Donne :
Code :
1
2
3
4
5
6
7
8
 
   	COLUMN_NAME	NUM_DISTINCT	HIDDEN_COLUMN	VIRTUAL_COLUMN
	ID_TEST		           5                            NO	          NO
	CHAMP1		           1                            NO	          NO
	CHAMP2		           2                            NO	          NO
	CHAMP3		           2                            NO	          NO
	CHAMP4		           2                            NO	          NO
	SYS_NC00006$		   1                            YES	          YES
__________________
Cordialement.
ORA-007 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 10h43   #8
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 926
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 926
Points : 4 547
Points : 4 547
ce n'est pas la bonne approche

au lieu de
Code :
1
2
CREATE INDEX i ON client(trunc(CLIENT_DATE));
SELECT * FROM CLIENT WHERE trunc(CLIENT_DATE) <= trunc(sysdate-1);
il est beaucoup plus simple, naturel et performant de faire
Code :
1
2
CREATE INDEX i ON client(CLIENT_DATE);
SELECT * FROM CLIENT WHERE CLIENT_DATE < trunc(sysdate);
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/09/2011, 11h47   #9
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
C'est pour l'égalité où ça ne marche pas ton exemple.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 13h34   #10
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 926
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 926
Points : 4 547
Points : 4 547
L'égalité de "trunc(date)=hier" est un fait une période entre hier matin et hier soir

Code :
SELECT * FROM CLIENT WHERE CLIENT_DATE < trunc(sysdate) AND CLIENT_DATE >= trunc(sysdate-1) ;
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 13h50   #11
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
Tu avoueras que pour ce cas, c'est moins intuitif comme code.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 17h16   #12
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 926
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 926
Points : 4 547
Points : 4 547
même sous la torture je n'avouerai rien du tout

ne pas utiliser < et > quand on a un index sur la date est un manque de logique !
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 17h37   #13
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183


non.. toujours pas ?

Bon, ça devient vite l'enfer si tu dois coder des IN avec plusieurs dates..



allez, un dernier pour la route :
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 18h35   #14
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par laurentschneider Voir le message
ne pas utiliser < et > quand on a un index sur la date est un manque de logique !
Manque de logique ou manque de pratique ?
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 09h00   #15
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Citation:
Envoyé par laurentschneider Voir le message
même sous la torture je n'avouerai rien du tout

ne pas utiliser < et > quand on a un index sur la date est un manque de logique !
Si je suis votre logique, quelque soit la situation dans laquelle on se trouve, avoir :
  1. un "Btree-index" sur une date
  2. un ''Function-based'' index sur une date
  3. un index partitionné sur une date
  4. un bitmap index sur une date
  5. etc.... sur une date
si dans cette situation nos requêtes sur cette date n'utilisent pas l'opérateur < ou l'opérateur > alors notre application(ou ceux qui l'ont conçue) manque de logique

C'est cela que vous voulez exprimez?
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 11h20   #16
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 926
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 926
Points : 4 547
Points : 4 547
Mohamed,

Oui, c'est ça le point, si celui qui a conçu l'application a fait du TRUNC(d) sans remarquer que le TRUNC(d) n'employait pas l'index sur la date, alors dans ce cas on pourrait faire un function-based-index sur le trunc.

Cependant si l'on écrit soit même l'application, alors pas de trunc et pas de fbi.

@McM : l'enfer c'est de devoir tuner avec des fbi des requetes qui durent des heures parceque les developpeurs ont eu la paresse d'écrire leur IN en BETWEEN

PS: un bitmap index sur une date sûrement pas! à moins que la date soit toujours le 14 juillet 1789 ou le 1 aout 1291
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h43.


 
 
 
 
Partenaires

Hébergement Web