Ça veut dire qu'on a lu le bloc qui contient la ligne après avoir trouvé son adresse dans l'index.
Version imprimable
Ca arrive souvent.
Vous renoncez un peu vite, non ?
Pour quoi voulez-vous qu'il y a une différence si l'index n'est pas utilisé ?
Hier ça avait l'air d'être bien ou je me trompe ? Cf. "Deuxième Requête avec like '%BS%'. Environ 1 secondes"
Qu'un index a été utilisé pour localiser les enregistrements et qu'ensuite le Rowid récupéré de l'index est utilisé pour accèder à la table.
Essayez d'écrire votre requête de la façon suivante
Code:
1
2
3
4
5
6 SELECT COUNT(produit.ProduitId) FROM Produit produit Where Exists (Select ... ) ...
Bonjour,
Juste un petit mot là dessus:
Au contraire: tu as une clé, il faut l'utiliser. Créer une clé supplémentaire, c'est le contraire de la normalisation: tu rajoute de la redondance.Citation:
Habitué à normaliser mes bases, j'utilise une clé primaire numérique.
Et en plus, pour des raisons de performances, tu vas te retrouver à mettre cette redondance dans les autres tables pour éviter des jointures.
Quel probléme y a-t-il à ce que la clé ne soit pas numérique ? au contraire tu peux alors:
- avoir un histogramme pour gérer la distribution SN%
- avoir envie de partitionner: les SN d'un côté par exemple.
Si tu veux normaliser, alors peut-être avoir des colonnes pour spécifiques (type de produit, date,...) pour que l'utilisateur n'aille pas deviner une date ou un code dans le numéro de série.
Pour quelle raison un number est mieux qu'un varchar sous MySQL ?Citation:
Ca me fait bizarre d'utiliser un varchar en clé primaire, mais c'est surement parce que je suis habitué à MySQL
Cordialement,
Franck.
Très étrange, je n'ai pas reçu d'alerte mail pour les nouvelles réponses.
Je pense pas avoir renoncer trop vite à la normalisation, j'ai déjà passer 2 semaines sur ce même problème ;).Citation:
Vous renoncez un peu vite, non ?
Non non, vu me qu’oracle fait un full scan, je comprend très bien pourquoi les temps sont similaire.Citation:
LIKE '%BS%' et LIKE 'BS%'.
Pour quoi voulez-vous qu'il y a une différence si l'index n'est pas utilisé ?
Je vais adapter ma requête avec la méthode EXIST, je vous tiendrais au courant.
Si j'utilise mon VARCHAR comme clé primaire de la table NUMSERIE, et donc comme clé étrangère également dans les autres tables. Je vais certainement ne pas faire les jointures jusqu'à NUMSERIE, et m'arrêter avant. Ne devrais-je pas alors partitionner le numéro de série dans les tables sous-jacente?
Non, je dis jusque qu'avec MySQL , on met un peu trop rapidement des clé primaire auto-incrémenté et que les varchar ne sont pas aussi bien géré que pour Oracle.Citation:
Pour quelle raison un number est mieux qu'un varchar sous MySQL ?
Voilà une requête équivalente.
Pourriez-vous la tester et me dire quelle est le résultat ?
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 SELECT COUNT(produit.ProduitId) FROM Produit produit Where Exists (Select Null From GROUPETEST groupeTest Where produit.ProduitId = groupeTest.ProduitId And Exists(Select Null From BANC banc Where banc.bancId = groupeTest.BancId And (banc.bancReference || banc.bancNumSerie LIKE '%BANC%' OR banc.bancName || banc.bancNumSerie LIKE '%BANC%') ) And Exists(Select Null From GROUPETESTNUMSERIE groupeTestNumSerie Where groupeTestNumSerie.groupeTestId = groupeTest.groupeTestId And groupeTestNumSerie.produitId = groupeTest.produitId And groupeTestNumSerie.siteId = 1 And Exists(Select Null From NUMSERIE numSerie Where numSerie.numSerieId = groupeTestNumSerie.numSerieId And numSerie.numSerie LIKE 'BS%' ) ) )
Je passe d'environ 9 secondes (Requete avec JOIN) à 6 secondes (Requête avec EXISTS). Cela pour les requêtes utilisant LIKE 'BS%'.
j'ai essayé avec les requêtes LIKE '%BS%' où il fait un full scan de la table du coup. La requête avec les JOIN met environ 0,5 seconde contre tps>1 seconde avec les EXISTS.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
28
29
30
31
32
33
34
35 -------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 18 | 583 (3)| 00:00:07 | | 1 | SORT AGGREGATE | | 1 | 18 | | | | 2 | NESTED LOOPS | | 1 | 18 | 583 (3)| 00:00:07 | | 3 | VIEW | VW_SQ_1 | 1 | 13 | 581 (3)| 00:00:07 | | 4 | HASH UNIQUE | | 1 | 81 | | | | 5 | NESTED LOOPS SEMI | | 1 | 81 | 581 (3)| 00:00:07 | |* 6 | HASH JOIN | | 1 | 46 | 580 (3)| 00:00:07 | | 7 | TABLE ACCESS BY INDEX ROWID| GROUPETESTNUMSERIE | 1 | 19 | 2 (0)| 00:00:01 | | 8 | NESTED LOOPS | | 17 | 595 | 573 (3)| 00:00:07 | | 9 | SORT UNIQUE | | 12 | 192 | 560 (3)| 00:00:07 | |* 10 | TABLE ACCESS FULL | NUMSERIE | 12 | 192 | 560 (3)| 00:00:07 | |* 11 | INDEX RANGE SCAN | GROUPETESTNUMSERIE_PK | 1 | | 1 (0)| 00:00:01 | | 12 | TABLE ACCESS FULL | GROUPETEST | 6611 | 72721 | 7 (0)| 00:00:01 | |* 13 | TABLE ACCESS BY INDEX ROWID | BANC | 2 | 70 | 1 (0)| 00:00:01 | |* 14 | INDEX UNIQUE SCAN | PK_BANC | 1 | | 1 (0)| 00:00:01 | |* 15 | INDEX UNIQUE SCAN | PRODUIT_PK | 1 | 5 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - access("GROUPETESTNUMSERIE"."GROUPETESTID"="GROUPETEST"."GROUPETESTID" AND "GROUPETESTNUMSERIE"."PRODUITID"="GROUPETEST"."PRODUITID") 10 - filter("NUMSERIE"."NUMSERIE" LIKE 'BS%' AND UPPER("NUMSERIE") LIKE 'BS%') 11 - access("NUMSERIE"."NUMSERIEID"="GROUPETESTNUMSERIE"."NUMSERIEID" AND "GROUPETESTNUMSERIE"."SITEID"=1) filter("GROUPETESTNUMSERIE"."SITEID"=1) 13 - filter("BANC"."BANCREFERENCE"||"BANC"."BANCNUMSERIE" LIKE '%BANC%' OR "BANC"."BANCNAME"||"BANC"."BANCNUMSERIE" LIKE '%BANC%') 14 - access("BANC"."BANCID"="GROUPETEST"."BANCID") 15 - access("PRODUIT"."PRODUITID"="PRODUITID")