Je ne comprends pas quelque chose au sujet de votre requête, je ne sais pas si je suis missunderstanding mais:
(SELECT COUNT(*) AS x
FROM (SELECT DISTINCT id
FROM streamsignature
WHERE time < '2013-01-03'
AND signature = 'v'
AND signaturelevel = 'check'
) AS subq
INNER JOIN files ON subq.id
est le nombre de lignes l'id de la table des fichiers? Comme vous, sur votre clause de jointure ont
ON subq.id = files.id
Et le seul champ sélectionné est x, et il est le nombre de lignes
... Quoi qu'il en soit
Je pense plus comme des problèmes d'index. Vous devriez vraiment utiliser EXPLAIN pour savoir quels index sont manquants.
Par exemple:
EXPLAIN SELECT * FROM orderdetails d
INNER JOIN orders o ON d.orderNumber = o.orderNumber
INNER JOIN products p ON p.productCode = d.productCode
INNER JOIN productlines l ON p.productLine = l.productLine
INNER JOIN customers c on c.customerNumber = o.customerNumber
WHERE o.orderNumber = 10101G
exécution de cette requête produira:
********************** 1. row **********************
id: 1
select_type: SIMPLE
table: l
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 7
Extra:
********************** 2. row **********************
id: 1
select_type: SIMPLE
table: p
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 110
Extra: Using where; Using join buffer
********************** 3. row **********************
id: 1
select_type: SIMPLE
table: c
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 122
Extra: Using join buffer
********************** 4. row **********************
id: 1
select_type: SIMPLE
table: o
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 326
Extra: Using where; Using join buffer
********************** 5. row **********************
id: 1
select_type: SIMPLE
table: d
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 2996
Extra: Using where; Using join buffer
5 rows in set (0.00 sec)`
Si vous regardez le résultat ci-dessus, vous pouvez voir tous les symptômes d'une mauvaise requête. Mais même si j'ai écrit une meilleure requête, les résultats seraient toujours les mêmes puisqu'il n'y a pas d'index. Le type de jointure est indiqué comme "ALL" (ce qui est le pire), ce qui signifie que MySQL n'a pas pu identifier les clés qui peuvent être utilisées dans la jointure et par conséquent les potentielles et les clés sont nulles. Plus important encore, la colonne rows montre que MySQL analyse tous les enregistrements de chaque table pour la requête. Cela signifie que pour exécuter la requête, il va scanner 7 × 110 × 122 × 326 × 2996 = 91 750 822 240 enregistrements pour trouver les quatre résultats correspondants. C'est vraiment horrible, et cela ne va qu'augmenter exponentiellement à mesure que la base de données se développe.
Maintenant, ajoutons des index évidents, tels que des clés primaires pour chaque table, et réexécutons la requête. En règle générale, vous pouvez considérer les colonnes utilisées dans les clauses JOIN de la requête comme de bons candidats pour les clés car MySQL analysera toujours ces colonnes pour trouver les enregistrements correspondants.
ALTER TABLE customers
ADD PRIMARY KEY (customerNumber);
ALTER TABLE employees
ADD PRIMARY KEY (employeeNumber);
ALTER TABLE offices
ADD PRIMARY KEY (officeCode);
ALTER TABLE orderdetails
ADD PRIMARY KEY (orderNumber, productCode);
ALTER TABLE orders
ADD PRIMARY KEY (orderNumber),
ADD KEY (customerNumber);
ALTER TABLE payments
ADD PRIMARY KEY (customerNumber, checkNumber);
ALTER TABLE productlines
ADD PRIMARY KEY (productLine);
ALTER TABLE products
ADD PRIMARY KEY (productCode),
ADD KEY (buyPrice),
ADD KEY (productLine);
ALTER TABLE productvariants
ADD PRIMARY KEY (variantId),
ADD KEY (buyPrice),
ADD KEY (productCode);
Laissez libre cours à re-de la même requête à nouveau après avoir ajouté les index et le résultat devrait ressembler à ceci:
********************** 1. row **********************
id: 1
select_type: SIMPLE
table: o
type: const
possible_keys: PRIMARY,customerNumber
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra:
********************** 2. row **********************
id: 1
select_type: SIMPLE
table: c
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra:
********************** 3. row **********************
id: 1
select_type: SIMPLE
table: d
type: ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 4
Extra:
********************** 4. row **********************
id: 1
select_type: SIMPLE
table: p
type: eq_ref
possible_keys: PRIMARY,productLine
key: PRIMARY
key_len: 17
ref: classicmodels.d.productCode
rows: 1
Extra:
********************** 5. row **********************
id: 1
select_type: SIMPLE
table: l
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 52
ref: classicmodels.p.productLine
rows: 1
Extra:
5 rows in set (0.00 sec)
Après l'ajout d'index, le nombre d'enregistrements numérisés a été ramené à 1 × 1 × 4 × 1 × 1 = 4. Cela signifie que pour chaque enregistrement avec orderNumber 10101 dans la table orderdetails, MySQL a pu trouver directement l'enregistrement correspondant dans toutes les autres tables en utilisant les index et n'a pas eu besoin de scanner l'ensemble table.
Pourquoi les jointures sont-elles si nombreuses? Est-ce que votre architecture l'exige? Avez-vous des index sur vos champs? – user1759572
ouais j'ai besoin de ces jointures coz je dois correspondre à ces valeurs de différentes tables, aussi pas tous les attributs sont indexés dans le db – trackmeifUcan
@ user2708115 S'il vous plaît afficher le résultat de 'EXPLAIN SELECT ...' et les structures de table (vous pouvez obtenir les avec la commande 'SHOW CREATE TABLE tablename' –
fancyPants