SELECT 1
FROM table_with_lot_of_rows
WHERE condition_on_index
LIMIT 1000, 1;
fonctionne de cette façon:
- Utilisation de l'index (qui est probablement plus rapide que d'utiliser les données)
- Passer plus de 1000 lignes, la collecte rien. (Cela vaut mieux que d'autres réponses.)
- Si vous arrivez si loin, récupérez 1 ligne, contenant uniquement le littéral
1
(dans le SELECT
). Maintenant, il faut soit
un jeu de résultats vide (< = 1000 lignes) ou une rangée de 1
(au moins 1001 lignes). Puis, en fonction de la langue de votre application, il est facile de distinguer les deux cas.
Une autre note: Si ce doit être une sous-requête dans une plus grande requête, puis faire
EXISTS (SELECT 1
FROM table_with_lot_of_rows
WHERE condition_on_index
LIMIT 1000, 1)
qui retourne VRAI/FAUX (qui sont synonymes de 1 ou 0). Face à cela, le balayage de 1001 lignes, même de l'index, prendra un certain temps. Je pense que ma formulation est la plus rapide possible.
Autres choses à vérifier: Est-ce InnoDB? Est-ce que EXPLAIN
dit "Using index"? Combien de RAM? Quel est le réglage de innodb_buffer_pool_size
? Notez que InnoDB a maintenant FULLTEXT, il n'y a donc aucune raison de rester avec MyISAM.
Si vous utilisez MyISAM et que le WHERE
est MATCH...
, la plupart de mes remarques risquent de ne pas s'appliquer. FULLTEXT
probablement récupère tous les résultats avant de donner le reste du moteur à la chance de faire ces jeux avec ORDER BY
et LIMIT
.
Veuillez nous montrer la requête réelle, ses EXPLAIN
et SHOW CREATE TABLE
. Et quel est le véritable objectif? Pour voir si une requête produira "trop" de résultats?
Amélioration possible (selon le contexte)
Depuis mes SELECT
initiales rendements scalaire 1
ou NULL
, il peut être utilisé dans un contexte booléen tel que WHERE
. 1
est TRUE
, NULL
sera traité comme FALSE
. Par conséquent EXISTS
est probablement redondant.
De même, 1
/NULL
peut être transformé en 1
/0
ainsi. Note: les parens supplémentaires sont requis.
IFNULL((SELECT ... LIMIT 1000,1), 0)
Excellente solution, merci! Donner les détails de mon paramètre spécifique pourrait être hors sujet pour cette question, qui était pour l'amélioration sur le 'count (*)> 1000' de base, et non lié aux index. – M1L0U
'FULLTEXT',' SPATIAL', 'PRIMARY', et d'autres index fonctionnent de 4 manières différentes. –
Après avoir offert la prime, je suis arrivé avec une version modifiée de ce qui obtient mon désiré "' 0' ou '1'" au lieu de "rien ou' 1' "comme résultat, sans répéter la valeur de seuil (qui viole DRY), mais c'est toujours basé sur la sous-requête (ce qui est moche). Je vais laisser la prime pour voir si quelqu'un peut le faire sans sous-requête pour les points de style, mais sinon, la prime est à vous pour m'inspirer. Ma version modifiée est juste l'emballage à 'COUNT' les résultats de votre requête:' SELECT COUNT (*) DE (SELECT 1 FROM table_with_lot_of_rows WHERE condition_on_index LIMIT 1000, 1); ' – ShadowRanger