Précédent   Forum des professionnels en informatique > Bases de données > Firebird > SQL
SQL Forum d'entraide sur le SQL pour Firebird
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 03/10/2011, 10h18   #1
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
Par défaut une addition dans la clause where : pb d'index ?

bonjour a tous


j'ai une table qui contient les informations sur une session (Qui, ou et quand)
et une table qui contient les détails de cette session (data). Cette table contient une colonne qui indique si l'action a eu lieu le jour de la session ou le lendemain
En effet, on peut commencer une session tard dans la nuit (23h00 par exemple et se poursuivre jusqu'au lendemain, disons 03h00 du matin). Aussi le passage d'une jour à l'autre est indiqué par une colonne "DATE_ADD" de la table DATA :
* 0 : l'action a eu lieu le même jour que le début de la session
* 1 : l'action s'est poursuivit le lendemain du début de la session
* ...

Afin de pouvoir tenir compte de cela, j'ai plusieurs requêtes qui ont cette structure (dans un but de lisibilité, je l'ai simplifiée au maximum ).

Code :
1
2
3
4
SELECT N_data.Id_data_princ
  FROM N_data
    INNER JOIN N_session ON (N_session.Id_session = N_data.Id_session)
WHERE N_session.Date_session = :Date_in
l’exécution de cette requête est très rapide (quelques ms).

Mais si je utilise la colonne DATE_ADD pour tenir compte de ces passages de jours, ainsi :
Code sql :
1
2
3
4
SELECT N_data.Id_data_princ
  FROM N_data
    INNER JOIN N_session ON (N_session.Id_session = N_data.Id_session)
WHERE N_session.Date_session + N_Data.Date_Add = :Date_in

Le temps d’exécution de celle ci devient très important (environ 10 sec. en utilisant bien les index crées).
Le changement majeure intervient dans la lecture de la table N_Data où le nombre de lectures indexées passe de 1500 dans le premier cas a plus de 4 000 000 dans le second.

Quelqu'un aurait-il une explication et surtout une solution ?

merci d'avance

olivier
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 11h12   #2
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 213
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 213
Points : 3 315
Points : 3 315
c'est quoi le plan dans les deux cas ?

et en écrivant :
Code :
WHERE N_session.Date_session  = (:Date_in - N_Data.Date_Add)
?
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 12h12   #3
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
bonjour Philippe

et merci pour ta réponse

1 . Avec WHERE N_session.Date_session = :Date_in,
le plan d'exécution est :
Citation:
PLAN JOIN (N_SESSION INDEX (IDX_N_SESSION_DATE), N_DATA INDEX (FK_BAGUE_ID_SESSION))

Query Time
------------------------------------------------
Prepare : 0.00 ms
Execute : 16.00 ms
Avg fetch time: 0.50 ms

Memory
------------------------------------------------
Current: 105*870*168
Max : 134*151*456
Buffers: 2*048

Operations
------------------------------------------------
Read : 137
Writes : 0
Fetches: 3*361
Marks : 0


Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records | Indexed | Non-Indexed | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
| | Total | reads | reads | | | | | | |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| N_DATA| 0 | 1505 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| N_SESSION| 0 | 69 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+

2 . Avec WHERE N_session.Date_session + N_Data.Date_Add = :Date_in, il est :
Citation:
PLAN JOIN (N_SESSION NATURAL, N_DATA INDEX (FK_BAGUE_ID_SESSION))

Query Time
------------------------------------------------
Prepare : 0.00 ms
Execute : 6*973.00 ms
Avg fetch time: 217.91 ms

Memory
------------------------------------------------
Current: 105*849*392
Max : 134*151*456
Buffers: 2*048

Operations
------------------------------------------------
Read : 104*905
Writes : 0
Fetches: 11*435*963
Marks : 0


Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records | Indexed | Non-Indexed | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
| | Total | reads | reads | | | | | | |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| N_DATA| 0 | 4481039 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| N_SESSION| 0 | 0 | 493370 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
3 . Et avec WHERE N_session.Date_session = :Date_in - N_Data.Date_Add, il est :
Citation:
PLAN JOIN (N_SESSION NATURAL, N_DATA INDEX (FK_BAGUE_ID_SESSION))

Query Time
------------------------------------------------
Prepare : 0.00 ms
Execute : 7*083.00 ms
Avg fetch time: 221.34 ms

Memory
------------------------------------------------
Current: 105*849*360
Max : 134*151*456
Buffers: 2*048

Operations
------------------------------------------------
Read : 104*913
Writes : 0
Fetches: 11*435*963
Marks : 0


Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records | Indexed | Non-Indexed | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
| | Total | reads | reads | | | | | | |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| N_DATA| 0 | 4481039 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| N_SESSION| 0 | 0 | 493370 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+

NB : l'écriture de la requête a été simplifiée pour sa lisibilité
NB1 : je suis sous 2.5 mais pas toute la dernière version.
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 14h35   #4
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 213
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 213
Points : 3 315
Points : 3 315
oui de fait, l'index ne peux pas être utilisé IDX_N_SESSION_DATE
puisque de toute façon, il faut calculer toutes les valeurs de N_session.Date_session + N_Data.Date_Add

sauf si N_Data.Date_Add ne peut être négatif (ce qui semble être le cas)
du coup il faudrait essayer qq chose du genre :

Code :
1
2
WHERE N_session.Date_session >= :Date_in
AND N_session.Date_session + N_Data.Date_Add = :Date_in

sinon il faut revoir le modèle et gérer ses dates autrements
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 15h31   #5
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
Merci philippe

j'ai utilisé ton petit truc et c'est quand même beaucoup mieux.


je l'ai juste modifié pour limité encore le nombre de possibilité, en considérant qu'il est hautement improbable que quelqu'un puisse travailler non-stop pendant plus de 3 jours

Code :
1
2
WHERE N_session.Date_session BETWEEN :Date_in AND :Date_in + 3
AND N_session.Date_session + N_Data.Date_Add = :Date_in
Merci encore

olivier
dehorter olivier 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 19h11.


 
 
 
 
Partenaires

Hébergement Web