2010-03-25 4 views
2

Supposons que j'ai une table à 2 colonnes (id, flag) et que id est séquentiel. Je m'attends à ce que cette table contienne beaucoup d'enregistrements. Je veux périodiquement sélectionner la première ligne non marquée et la mettre à jour. Certains des enregistrements en cours ont déjà été marqués, je veux donc les ignorer.lequel est une pratique SQL plus rapide/meilleure?

-t-il plus de sens que si je stocke le dernier id je hélé et l'utiliser dans mon instruction select, comme

select * from mytable where id > my_last_id order by id asc limit 1 

ou simplement obtenir la première ligne sans pavillon, comme:

select * from mytable where flagged = 'F' order by id asc limit 1 

Je vous remercie!

+0

(peut-être une faute de frappe) Est-ce que "flagged = 'F' 'signifie que votre enregistrement est non-marqué? –

+0

bon point .. F signifie faux – artsince

Répondre

0

En supposant MySQL, celui-ci:

SELECT * 
FROM mytable 
WHERE flagged = 'F' 
ORDER BY 
     flagged ASC, id ASC 
LIMIT 1 

sera légèrement moins efficace dans InnoDB et de même efficacité dans MyISAM, si vous avez un index sur (flagged, id).

InnoDB Les tables sont regroupées sur PRIMARY KEY. L'extraction du premier enregistrement dans id ne nécessite donc pas de rechercher la table.

Dans MyISAM, les tables sont organisées en tas, de sorte que l'index utilisé pour contrôler le PRIMARY KEY est stocké séparément de la table.

Notez que le flagged dans la clause ORDER BY peut sembler être redondant, mais il est nécessaire pour MySQL de choisir l'index correct.

En outre, l'index composite doit être sur (flagged, id) même en InnoDB (ce qui inclut implicitement le PRIMARY KEY dans chaque index).

+0

quel est le point de commande par 'flagged' puisque c'est le filtre (* avec une valeur admise dans le resultset *) ... c'est inutile ... –

+0

@Gaby: cela aidera 'MySQL' à choisir l'index correct. – Quassnoi

+0

@Quassnoi, si c'est un problème intrinsèque avec la mise en œuvre alors je déclare mon ignorance sur elle :) il semble juste assez non-intuitif .. (edit: merci pour les infos supplémentaires, fait plus de sens maintenant :)) –

2

L'option deux est la seule qui a du sens à moins que vous sachiez que vous allez toujours traiter les enregistrements dans l'ordre!

+0

Je sais que je vais toujours les traiter dans l'ordre. – artsince

+0

il utilise un «ordre par» sur la clé d'identification .. donc il est toujours en séquence .. –

+0

@Gaby, je me rends compte de cela, mais rien ne dit qu'il ne pouvait pas y avoir des enregistrements non traités avec un ID inférieur à "dernier ID traité". Cela vous laisserait des trous dans vos données qui ne pourraient jamais être remplis en fonction de la logique de la première requête. – ninesided

3

Si vous créez un index sur marqué, la récupération d'une ligne non marquée doit être une opération quasi instantanée. Si vous les mettez toujours à jour séquentiellement, la première méthode est correcte.

0

Vous pouvez utiliser

Select Min(Id) as 'Id' 
From dbo.myTable 
Where Flagged='F' 

En supposant que le Signalé = 'F' signifie qu'il est pas marqué.

+0

.. mais il demande '*' non seulement l'id .. –

+0

Ah oui bien sûr. Bien que je ne suis pas sûr pourquoi vous * dans ce scénario. – codingbadger

Questions connexes