J'ai des problèmes de performances sur certaines requêtes de base de données qui ont des ensembles de résultats possibles importants.
La requête en question, j'ai trois AND
s dans la clause WHERE
L'ordre des articles est-il important?
Comme dans, si je mets la clause ASI_EVENT_TIME en premier (car cela enlèverait la plupart des résultats de toutes les clauses.
Cela améliorera-t-il le temps d'exécution de la requête?
QUESTION:
SELECT DISTINCT activity_seismo_info.*
FROM `activity_seismo_info`
WHERE
activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL AND
activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND
(
activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND
activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
)
ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC
EXPLAIN de requête:
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5 | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
En utilisant:
PHP 5.2
MySQL 5.0.51a-3ubuntu5.4
Propel 1.3
Symfony 1.2.5
mysql
performance
mysql-5
Patrick
la source
la source
order by
appartient à la base de données.Réponses:
Je ne pense pas. L'optimiseur de requête devrait être assez intelligent.
Vous pouvez essayer de réorganiser les clauses WHERE et voir que EXPLAINS vous dit la même chose dans chaque cas.
A propos de ce qui peut être fait pour optimiser cette requête: Existe-t-il un index sur ASI_EVENT_TIME? (C’est le plus crucial, je pense, pour cette requête car vous triez également les résultats à l’aide de cette requête).
Existe-t-il des index sur les deux autres champs (ASI_SEISMO_ID et ASI_ACTIVITY_ID)?
Il serait utile de publier la structure de la table.
la source
De la documentation :
Alors oui, il devrait être identique à l'ordre des colonnes dans un index composé .
la source
WHERE c = 'foo' AND a = 'bar' AND b = 'foobar'
, l’indice est toujours utilisable.Non, ce n'est pas grave.
L’optimiseur effectue une série de transformations simples immédiatement après l’analyse du code SQL - c’est l’une d’elles.
la source
optimise le même que
cependant,
Impossible d'optimiser les deux parties. Par exemple,
ne peut pas utiliser correctement INDEX (a, b) ou INDEX (b, a)
Pour le formuler différemment, tous les tests '=' ET combinés dans la clause WHERE sont utilisés en premier, puis un non - '=' (IN, BETWEEN,>, etc.) peut être traité. Pas plus d'un ne peut être efficacement optimisé.
Votre requête a 3 telles clauses.
En fait, INDEX (EVENT_TIME) est probablement le plus utile - il aidera avec l’un des AND, et pourrait être utilisé pour éviter le "fichier" pour ORDER BY.
S'il n'y a pas de lignes en double (pourquoi diable y aurait-il?), Supprimez DISTINCT. Cela provoque encore plus d'effort.
Veuillez indiquer SHOW CREATE TABLE et SHOW TABLE STATUS lorsque vous posez des questions sur les performances.
Mettre à jour ... Les versions les plus récentes (par exemple, MySQL 5.7) peuvent, dans certaines situations, traiter
IN( list of constants )
presque de la même manière=
. Pour jouer en toute sécurité, respectez cet ordre (chaque partie étant optionnelle):=
.INs
.la source
MySQL où le document d'optimisation dit:
De cette façon, il est rationnel que l'optimiseur de requête omette l'ordre HOW. Nous avons utilisé les colonnes de la requête (non seulement MySQL, mais SQL est un langage déclaratif et doit faire ce que nous voulons et non ce que nous voulons).
Cependant, j'aime toujours avoir le même type pour les colonnes d'une clé composite dans la requête, mais cela est parfois inévitable, par exemple lorsque nous utilisons ORM ou ActiveRecord, dans certains frameworks tels que yii2, la personnalisation des critères de relation sera ajoutée à la fin de. une condition "on" mais nous avons toujours besoin des capacités de QueryBuilders dans différentes parties d'une application.
la source
TOUT champ utilisé dans vos clauses WHERE / HAVING et ayant une sélectivité élevée (nombre de valeurs uniques / nombre total d'enregistrements> 10% à 20%) DOIT être indexé.
Donc, si votre
ASI_EVENT_TIME
colonne a plusieurs valeurs possibles, commencez par les indexer. Puis, comme @ypercube l'a dit, essayez de les réorganiser et voyez ce que EXPLAIN vous dit. Devrait être tout autour de la même chose.De plus, vous souhaitez jeter un coup d'œil à l' indexation des filtres SQL LIKE . Bien que ce ne soit pas ce pour quoi vous avez besoin d’une réponse, vous apprendrez tout de même comment fonctionne l’indexation sous le capot.
* Modifier: reportez - vous aux liens fournis ci-dessous dans les commentaires pour en savoir plus sur l'indexation.
la source