2010-03-15 3 views
1

J'ai une table de données qui est consultable et triable, mais susceptible de produire des centaines ou des milliers de résultats pour des recherches larges. En supposant que les recherches des utilisateurs pour « foo » et trie les foos dans l'ordre décroissant de prix que je voudrais montrer un menu de sélection rapide saut comme ceci:comment tirer et afficher les données de plage (min-max) pour chaque page en pagination?

<option value="1">Page 1 ($25,000,000 - $1,625,000)</option> 
<option value="2">Page 2 ($1,600,000 - $1,095,000)</option> 
<option value="3">Page 3 ($1,095,000 - $815,000)</option> 
<option value="4">Page 4 ($799,900 - $699,000)</option> 
... 

Y at-il un moyen efficace d'interroger ces informations directement à partir la DB? J'ai saisi tous les enregistrements correspondants et utilisé PHP pour calculer la valeur min et max pour chaque page qui semble inefficace et susceptible de causer des problèmes de mise à l'échelle. La seule technique que j'ai pu trouver est une façon d'avoir une variable calculée qui incrémente tous les enregistrements X (enregistrements X sur une page), en les regroupant et en sélectionnant MIN/MAX pour chaque page regroupement ... malheureusement, je n'ai pas réussi à trouver un moyen de générer cette variable.

Répondre

2

Bien que techniquement possible, je vous conseille de ne pas perdre de temps avec cette fonctionnalité, et chercher une autre approche.

Tout d'abord, quelques informations de base sur la pagination. La pagination est généralement accomplie en utilisant ORDER BY ... LIMIT [offset], [rows]. Afin que MySQL vous fournisse les lignes à un décalage donné, il doit lire toutes les lignes avant de les jeter. C'est cher et le coût augmente avec l'offset qui augmente. (par exemple LIMIT 1000, 20 doit lire 1020 lignes, puis jeter 1000). C'est encore pire quand ORDER BY ne peut pas être accompli en utilisant un index. Cela peut entraîner ensemble résultats illimités étant lus, puis filesorted, et puis les 1000 premières lignes sont jetées pour satisfaire un LIMIT 1000, 20.

Maintenant, abordons votre problème spécifique. Comme indiqué, la pagination n'est rien de "magique"; C'est une façon plutôt brute de paginer les résultats. Plus précisément, vous ne savez pas à quelle page quelque chose tombe à l'avance sans faire une sorte sur l'ensemble du résultat. Pour comprendre cela, vous devez utiliser des tables temporaires, puis calculer la valeur min/max par page de votre ensemble de résultats à partir de cette table temporaire. Si vos données sont volatiles, vous devez les recalculer aussi souvent que les données sous-jacentes changent.

Si le moteur de stockage stockait en quelque sorte la "page" de chaque ligne pour un ordre donné, vous pourriez le faire relativement facilement. Malheureusement, ce n'est pas le cas.

De plus, je doute de l'utilité de votre approche pour vos utilisateurs. Votre exemple montre une belle distribution des prix. Pouvez-vous être sûr que vous ne finiriez pas avec des gammes comme les suivantes?

<option value="1">Page 1 ($1,005,000 - $1,004,000)</option> 
<option value="2">Page 2 ($1,004,000 - $1,003,450)</option> 
<option value="3">Page 3 ($1,003,450 - $1,003,387)</option> 
<option value="4">Page 4 ($1,003,387 - $1,003,342)</option> 

Je doute que ce serait un avantage pour l'utilisateur.

Suggestion

  • Gardez votre
  • simple, la pagination
  • Si vous souhaitez que les utilisateurs soient en mesure de choisir une gamme de prix, puis construire que comme un filtre - ne se combinent pas avec pagination.

Exemple

Rechercher quelque chose sur Amazon et notez leur page de résultats. Vous obtiendrez vos résultats de recherche simplement paginés. Sur la gauche, vous aurez une variété de filtres à appliquer à votre recherche pour l'affiner davantage.

+0

Ouais c'est essentiellement la conclusion à laquelle je venais aussi ... Je ne savais pas s'il me manquait quelque chose d'intelligent qui ferait que ça marche bien. FWIW Je connais LIMIT/OFFSET dans les requêtes et la seule raison pour laquelle il n'est pas utilisé est parce que nous devions regarder chaque ligne du résultat en php pour construire le min/max par page de toute façon. Cela soulève cependant une autre question ... si MySQL doit de toute façon regarder les premières X pour les compenser, est-ce bien pire de tout retourner à chaque fois et de parcourir l'ensemble en PHP? –

+0

@Ty: Oui. Tout ce que PHP fait, MySQL (C) fait 10-100x plus vite. – hobodave

+0

@Ty: ressource d'optimisation de la pagination: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf – hobodave

Questions connexes