2010-12-07 41 views
0

Supposons que la table X ait 100 tuples.Est-il correct de scanner une table dans MySQL en utilisant "SELECT * .. LiMIT start, count" sans clause ORDER BY?

Est-ce que l'approche suivante de la numérisation X va générer tous les tuples dans le TABLEAU X, dans MySQL?

 
for start in [0, 10, 20, ..., 90]: 
    print results of "select * from X LIMIT start, 10;" 

Je demande, parce que je me sers de PostgreSQL, qui dit clairement que cette approche need not work, mais il semble y avoir aucune info pour MySQL. Si ce n'est pas le cas, existe-t-il un moyen de renvoyer les résultats dans un ordre fixe sans connaître d'autres informations sur la table (comme ce sont les champs clés primaires)? J'ai besoin de scanner chaque ligne dans une table dans une application, et je veux un moyen de le faire sans utiliser trop de mémoire dans l'application (donc simplement faire un "select * from X" est sorti).

Répondre

1

Si vous utilisez des types de tables Innodb ou MyISAM, une meilleure approche consiste à utiliser l'interface HANDLER. Seul MySQL prend en charge, mais il fait ce que vous voulez:

http://dev.mysql.com/doc/refman/5.0/en/handler.html

En outre, l'API MySQL prend en charge deux modes de récupération de données à partir du serveur:

  1. résultat du magasin: dans ce mode, comme Dès qu'une requête est exécutée, l'API récupère l'intégralité du jeu de résultats avant de revenir au code utilisateur. Cela peut utiliser beaucoup de résultats de mise en mémoire tampon de la mémoire client, mais minimise l'utilisation des ressources sur le serveur.
  2. résultat d'utilisation: dans ce mode, l'API extrait les résultats ligne par ligne et renvoie le contrôle au code utilisateur plus fréquemment. Cela minimise l'utilisation de la mémoire sur le client, mais peut maintenir des verrous sur le serveur plus longtemps.

La plupart des API MySQL pour différentes langues le supportent sous une forme ou une autre. C'est en général un argument qui peut être fourni comme lors de la création de la connexion, et/ou un appel distinct qui peut être utilisé contre une connexion existante pour la passer dans ce mode.

Ainsi, en réponse à votre question - je faire ce qui suit:

set the connection to "use result" mode; 
select * from X 
+0

Wow! Le résultat d'utilisation est juste ce que le docteur a commandé pour mon application. Merci pour la réponse! – donatello

3

Non, ce n'est pas une hypothèse sûre. Sans clause ORDER BY, il n'y a aucune garantie que votre requête retournera des résultats uniques à chaque fois. Si cette table est correctement indexée, l'ajout d'un ORDER BY (pour l'index) ne devrait pas être trop cher.

Editer: Non ORDER BY ed résultats parfois être dans l'ordre de l'index cluster, mais je ne mettrais pas d'argent sur cela!

+0

Si une ligne est insérée lors de la boucle, rien ne garanties Il briser l'ordre, même avec une clause 'ORDER BY' , sauf dans une connexion sécurisée. – Danosaure