MySQL WHERE vs HAVING : optimisation des requêtes avec des colonnes calculées
Dans les opérations de base de données MySQL, le choix entre les clauses WHERE
et HAVING
affecte considérablement l'efficacité des requêtes lors du traitement des colonnes calculées. Comprendre leurs rôles distincts est crucial pour écrire du SQL optimisé.
Placement stratégique des colonnes calculées
Les colonnes calculées, telles que celles créées dans l'instruction SELECT
(par exemple, SELECT 1 AS "number"
), doivent généralement suivre la clause HAVING
, et non WHERE
. En effet, WHERE
filtre les données avant tout calcul ou agrégation, tandis que HAVING
filtre après ces opérations.
Limitations de la clause WHERE
L'utilisation de WHERE
avec des colonnes calculées entraîne souvent des erreurs. WHERE
les conditions doivent faire référence à des colonnes ou à des alias de table existants ; il ne peut pas opérer directement sur les valeurs calculées.
Différences clés entre OÙ et AVOIR
WHERE
Clause : Filtre les lignes avant l'exécution de l'instruction SELECT
. Les conditions peuvent être appliquées à n'importe quelle colonne de tableau, mais pas aux colonnes calculées définies dans la liste SELECT
.
HAVING
Clause : Filtre les lignes après l'instruction SELECT
et les fonctions d'agrégation ont été appliquées. Les conditions peuvent être appliquées aux colonnes, aux alias ou aux résultats de fonctions d'agrégation sélectionnés.
Considérations relatives aux performances
Pour les grandes tables, placer des colonnes calculées dans la clause WHERE
peut être coûteux en termes de calcul. HAVING
offre un avantage en termes de performances dans ces scénarios car il fonctionne sur un ensemble de données réduit (les résultats de l'instruction SELECT
), minimisant ainsi le filtrage de lignes inutile.
Exemple illustratif
Considérons un exemple de tableau :
<code class="language-sql">CREATE TABLE `table` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `value` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `value` (`value`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</code>
Rempli avec dix lignes (identifiant et valeur allant de 1 à 10) :
<code class="language-sql">INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);</code>
Les requêtes suivantes donnent des résultats identiques :
<code class="language-sql">SELECT `value` v FROM `table` WHERE `value`>5; -- Returns 5 rows SELECT `value` v FROM `table` HAVING `value`>5; -- Returns 5 rows</code>
Cependant, EXPLAIN
révèle une distinction de performance cruciale :
<code class="language-sql">EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5; -- Uses index but scans more rows EXPLAIN SELECT `value` v FROM `table` HAVING `value`>5; -- Uses index efficiently, scans fewer rows</code>
Alors que les deux utilisent un index, WHERE
analyse une plus grande partie de la table à filtrer, tandis que HAVING
fonctionne plus efficacement sur un sous-ensemble plus petit et pré-filtré. Cette différence devient de plus en plus prononcée avec des ensembles de données plus volumineux. Par conséquent, pour les colonnes calculées, HAVING
offre généralement de meilleures performances.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!