SQL Server 2008 pagination méthodes?
J'ai de travailler avec potentiellement une large liste de dossiers et j'ai été Googler pour les moyens d'éviter la sélection de l'ensemble de la liste, au lieu de cela, je veux permettre aux utilisateurs de sélectionner une page (par exemple de 1 à 10) et d'afficher les dossiers en conséquence.
Dire, pour 1000 enregistrements, je vais avoir 100 pages de 10 dossiers chaque et la plus récente 10 enregistrements seront affichés en premier, puis si l'utilisateur clique sur la page 5, il va afficher les enregistrements de 41 à 50.
Est-ce une bonne idée d'ajouter un numéro de ligne pour chaque enregistrement une requête basée sur le numéro de ligne? Est-il une meilleure façon de parvenir à la pagination résultat sans trop de frais généraux?
Jusqu'à présent, ces méthodes comme décrit ici l'aspect le plus prometteur:
http://developer.berlios.de/docman/display_doc.php?docid=739&group_id=2899
http://www.codeproject.com/KB/aspnet/PagingLarge.aspx
OriginalL'auteur fred | 2010-12-05
Vous devez vous connecter pour publier un commentaire.
Les T-procédure stockée SQL est un très la mise en œuvre efficace de la pagination. LE SQL de l'optimiseur peut trouver l'ID du premier très rapide. Combinez cela avec l'utilisation de nombre de lignes, et vous avez une approche qui est à la fois CPU-efficace et la lecture efficace. Pour une table avec un grand nombre de lignes, il est certainement beaucoup mieux que toute approche que j'ai vu à l'aide d'une table temporaire ou une variable de table.
NB: je suis en utilisant une séquence de colonne d'identité dans cet exemple, mais le code fonctionne sur n'importe quelle colonne adapté pour la page de tri. Aussi, séquence de sauts dans la colonne utilisée n'affectent pas le résultat que le code sélectionne un certain nombre de lignes plutôt que la valeur d'une colonne.
EDIT: Si vous êtes de tri sur une colonne avec potentiellement non-valeurs uniques (par exemple, Nom de famille), puis ajouter une deuxième colonne de la clause Order By pour faire le tri des valeurs uniques de nouveau.
id sauts de pas faire de différence à ce code, car le haut de la taille est le nombre de lignes dans la page (pas le numéro d'id).
aussi, la colonne utilisée n'a pas besoin d'être un id incrémentielle. Vous pouvez utiliser n'importe quelle colonne pour le tri.
+1 Pourquoi utiliser
SET ROWCOUNT
plutôt queTOP
si?Sur la réflexion à ce sujet. Cela va faire 2 index différents scans, j'aurais pensé que ce serait un peu moins efficaces, alors seulement à l'aide de
row_count
et il fait tout en un seul scan car il aura pour naviguer dans l'index racine et intermédiaires pages de "trouver sa place" lors de laWHERE [Id] >= @FirstId bit
. C'est en supposant que les deux analyses seront sur le même indice. Je suppose que si la première analyse ont été à l'encontre d'une très étroite index sur seul id et le second à l'encontre d'un index de couverture avecid
comme le principal champ de ce qui pourrait mieux fonctionner!OriginalL'auteur RoadWarrior
Si vous utilisez une expression de table commune avec deux row_number() colonnes - triés asc, un desc, vous obtenez les numéros de ligne pour l'échange ainsi que le nombre total d'enregistrements en ajoutant les deux row_number colonnes.
Aussi, vous pouvez utiliser ", Count(*) SUR() total_row_count", qui sera de retour une colonne avec le même nombre de nouveau.
OriginalL'auteur 3Dave
À l'aide d'OFFSET
D'autres ont expliqué comment la
ROW_NUMBER() OVER()
fonction de classement peut être utilisé pour effectuer pages. Il convient de mentionner que SQL Server 2012 enfin, la prise en charge de la norme SQLDÉCALAGE .. FETCH
clause:Si vous utilisez SQL Server 2012 et de la rétro-compatibilité n'est pas un problème, vous devriez probablement préférer cette clause comme il sera exécuté de façon plus optimale par SQL Server en cas de coin.
À l'aide de la Méthode de recherche
Il est tout à fait différent, beaucoup plus rapide pour effectuer l'échange en SQL. Ceci est souvent appelé la "méthode de recherche", comme décrit dans ce billet de blog ici.
La
@previousScore
et@previousPlayerId
valeurs sont les valeurs respectives du dernier enregistrement de la page précédente. Cela vous permet de chercher les "à côté" de la page. Si leORDER BY
direction estASC
, il suffit d'utiliser>
à la place.Avec la méthode ci-dessus, vous ne pouvez pas sauter immédiatement à la page 4, sans avoir d'abord cherché le précédent de 40 dossiers. Mais souvent, vous ne voulez pas sauter aussi loin de toute façon. Au lieu de cela, vous obtenez un beaucoup plus rapide requête qui pourrait être en mesure d'extraire des données en temps constant, en fonction de votre indexation. De Plus, vos pages de rester "stable", peu importe si les données sous-jacentes des changements (p. ex., page 1, alors que vous êtes sur la page 4).
C'est la meilleure façon de mettre en œuvre la pagination lorsque le chargement paresseux plus de données dans les applications web, par exemple.
Note, la "méthode de recherche" est aussi appelé jeu de clés de pagination.
Alors qu'un bon cas peut être faite que de sauter à la page de l'INTERFACE utilisateur de recherche ne sont pas une grande conception de toute façon, je pense que vous avez vraiment besoin de montrer à vos utilisateurs comment de nombreux résultats de leur recherche a renvoyé (ou au moins une approximation, comme Google le fait, même si je ne suis pas sûr que toutes les bases de données SQL ce genre de fonctionnalité). Donc, cette méthode nécessite un supplément compter de la requête, ce qui augmente le coût de beaucoup.
Cela peut être un YMMV chose, mais j'ai fait une comparaison entre cette méthode seek (sur sql server 2008, hélas) et le "saint graal" de la méthode de la sqlservercentral article, qui vous donne le comte, et deux d'effectuer assez similaire. En ajoutant le coût du comte de requête à la méthode seek cependant fait le graal de la requête le gagnant clair.
OriginalL'auteur Lukas Eder
Essayer quelque chose comme cela:
ne devrait-elle pas être " declare @inférieur int = (@page * @taille) - (@taille - 1)'
Lien intéressant. Je l'ai ajouté à mon récent blog à propos de la plus rapide d'échange. Savez-vous à propos de la méthode de recherche? Il ne permet pas de vrai indexé décalages, mais peut sauter à la prochaine page en temps constant.
Dans les tests, @ReidEvans est correct, il doit être (page@ * @taille) - (@taille - 1). Le (@page - 1) * @taille renvoie les lignes 1 à 10, puis de 10 à 20 au lieu de 11-20 comme prévu.
OriginalL'auteur bernd_k
Voici une version mise à jour de @RoadWarrior code, à l'aide de HAUT. La Performance est identique, et extrêmement rapide. Assurez-vous d'avoir un indice sur TestTable.ID
OriginalL'auteur Lane
Essayer cette
OriginalL'auteur Aalkhodiry
Pourquoi ne pas utiliser recommandé solution:
OriginalL'auteur Vladimir Sosnin