Parmi les requêtes suivantes, quelle méthode considérez-vous comme la meilleure? Quelles sont vos raisons (efficacité du code, meilleure maintenabilité, moins de WTFery) ...
Dans le pire des cas, lorsque vous regardez un champ non indexé, l'utilisation MIN()nécessite un seul passage complet de la table. L'utilisation de SORTet LIMITnécessite un tri de fichiers. Si elle était exécutée sur une grande table, il y aurait probablement une différence significative dans les performances perçues. En tant que point de données sans signification, il a MIN()fallu 0,36 s SORTet LIMIT0,84 contre une table de 106 000 lignes sur mon serveur de développement.
Si, cependant, vous regardez une colonne indexée, la différence est plus difficile à remarquer (le point de données sans signification est de 0,00 s dans les deux cas). Cependant, en regardant la sortie d'Expliquer, il semble être MIN()capable de simplement extraire la plus petite valeur de l'index (lignes `` Sélectionner les tables optimisées '' et `` NULL '') alors que SORTet LIMITdoit encore effectuer un parcours ordonné de l'index (106 000 lignes). L'impact réel sur les performances est probablement négligeable.
Il semble que MIN()c'est la voie à suivre - c'est plus rapide dans le pire des cas, impossible à distinguer dans le meilleur des cas, c'est du SQL standard et exprime le plus clairement la valeur que vous essayez d'obtenir. Le seul cas où il semble que l'utilisation de SORTet LIMITserait souhaitable serait, comme l' a mentionné mson , où vous écrivez une opération générale qui trouve les N valeurs supérieures ou inférieures à partir de colonnes arbitraires et cela ne vaut pas la peine d'écrire l'opération de cas spécial.
o (n) pour un seul passage vs 0 (nlogn) pour le tri
Abhishek Iyer
1
@AbhishekIyer vous avez tout à fait raison, mais j'ajouterais "dans le pire des cas pour un champ non indexé".
dmikam
Cette partie du pire cas non indexé est fausse. Vous avez toujours besoin d'une analyse complète, comment savez-vous que c'est un minimum ou un maximum? Ce n'est pas comme si vous scanniez et que la valeur hurlait: "Hé, tu m'as enfin trouvé! Je suis Jack, le max!".
Robo Robok
Dans un test avec une table indexée avec 470 millions de lignes, les deux requêtes prennent 0,00 s. Cependant, si nous ajoutons aux requêtes un filtre "WHERE champ2 = x", la requête avec LIMIT prend toujours 0,00 s et la requête avec MIN prend 0,21 s.
Antonio Cañas Vargas
12
SELECT MIN(`field`)FROM`tbl`;
Tout simplement parce qu'il est compatible ANSI. La limite 1 est particulière à MySql comme TOP l'est à SQL Server.
La plupart des SGBD ont une limite / décalage ou équivalent, et il est utilisé dans la majorité des applications sur lesquelles j'ai travaillé (pas comme une alternative à MIN, mais à d'autres fins telles que la pagination.)
finnw
@finnw - Je suis d'accord, mais l'exemple du questionneur comparait explicitement la limite à min.
Je pense que les réponses dépendent de ce que vous faites.
Si vous avez une requête 1 off et que l'intention est aussi simple que vous l'avez spécifiée, sélectionnez min (champ) est préférable.
Cependant, il est courant que ces types d'exigences se transforment en - saisir les n premiers résultats, saisir les nièmes - mois, etc.
Je ne pense pas que ce soit une idée trop terrible de s'engager dans la base de données choisie. Changer les dbs ne doit pas être fait à la légère et doit réviser le prix que vous payez lorsque vous faites ce mouvement.
Pourquoi vous limiter maintenant, pour la douleur que vous ressentirez ou non plus tard?
Je pense qu'il est bon de rester ANSI autant que possible, mais ce n'est qu'une ligne directrice ...
Avec des performances acceptables, j'utiliserais le premier car il est sémantiquement plus proche de l'intention.
Si les performances étaient un problème (la plupart des optimiseurs modernes optimiseront probablement les deux pour le même plan de requête, bien que vous deviez tester pour le vérifier), alors bien sûr, j'utiliserais le plus rapide.
Tout simplement parce qu'il est compatible ANSI. La limite 1 est particulière à MySql comme TOP l'est à SQL Server.
la source
Comme l' ont souligné mson et Sean McSomething , MIN est préférable.
Une autre raison pour laquelle ORDER BY + LIMIT est utile est si vous souhaitez obtenir la valeur d'une colonne différente de la colonne MIN.
Exemple:
la source
Je pense que les réponses dépendent de ce que vous faites.
Si vous avez une requête 1 off et que l'intention est aussi simple que vous l'avez spécifiée, sélectionnez min (champ) est préférable.
Cependant, il est courant que ces types d'exigences se transforment en - saisir les n premiers résultats, saisir les nièmes - mois, etc.
Je ne pense pas que ce soit une idée trop terrible de s'engager dans la base de données choisie. Changer les dbs ne doit pas être fait à la légère et doit réviser le prix que vous payez lorsque vous faites ce mouvement.
Pourquoi vous limiter maintenant, pour la douleur que vous ressentirez ou non plus tard?
Je pense qu'il est bon de rester ANSI autant que possible, mais ce n'est qu'une ligne directrice ...
la source
Avec des performances acceptables, j'utiliserais le premier car il est sémantiquement plus proche de l'intention.
Si les performances étaient un problème (la plupart des optimiseurs modernes optimiseront probablement les deux pour le même plan de requête, bien que vous deviez tester pour le vérifier), alors bien sûr, j'utiliserais le plus rapide.
la source