Quelle est la meilleure façon (en termes de performances) de paginer les résultats dans SQL Server 2000, 2005, 2008, 2012 si vous souhaitez également obtenir le nombre total de résultats (avant la pagination)?
sql
sql-server
performance
pagination
Panagiotis Korros
la source
la source
Réponses:
Obtenir le nombre total de résultats et paginer sont deux opérations différentes. Pour les besoins de cet exemple, supposons que la requête que vous traitez est
Dans ce cas, vous détermineriez le nombre total de résultats en utilisant:
... qui peut sembler inefficace, mais est en fait assez performant, en supposant que tous les index, etc. sont correctement configurés.
Ensuite, pour obtenir les résultats réels de manière paginée, la requête suivante serait la plus efficace:
Cela renverra les lignes 1 à 19 de la requête d'origine. La chose intéressante ici, en particulier pour les applications Web, est que vous n'avez pas à conserver d'état, sauf les numéros de ligne à renvoyer.
la source
Enfin, Microsoft SQL Server 2012 est sorti, j'aime beaucoup sa simplicité pour une pagination, vous n'avez pas besoin d'utiliser des requêtes complexes comme répondu ici.
Pour obtenir les 10 lignes suivantes, exécutez simplement cette requête:
https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql#using-offset-and-fetch-to-limit-the-rows- revenu
Points clés à considérer lors de son utilisation:
ORDER BY
est obligatoire d'utiliser laOFFSET ... FETCH
clause.OFFSET
clause est obligatoire avecFETCH
. Vous ne pouvez pas utiliserORDER BY ... FETCH
.TOP
ne peut pas être combiné avecOFFSET
etFETCH
dans la même expression de requête.la source
LISTAGG()
/GROUP_CONCAT()
.FOR XML
: stackoverflow.com/a/273330/429949FOR XML PATH ('')
. Tout d'abord, il remplace les caractères de contrôle XML par des codes d'entité XML. Je espère que vous n'avez pas<
,>
ou&
dans vos données! Deuxièmement, laFOR XML PATH ('')
syntaxe en fait non utilisée est utilisée de cette manière. Vous êtes censé spécifier une colonne nommée ou un autre nom d'élément. Ne faire ni l'un ni l'autre n'est pas dans le document, ce qui signifie que le comportement n'est pas fiable. Troisièmement, plus nous acceptons laFOR XML PATH ('')
syntaxe cassée , moins il est probable que MS fournisse réellement une fonction réelleLISTAGG() [ OVER() ]
comme ils en avaient besoin.Incroyablement, aucune autre réponse n'a mentionné le moyen le plus rapide de paginer dans toutes les versions de SQL Server. Les décalages peuvent être terriblement lents pour les grands nombres de pages, comme c'est le cas ici . Il existe un moyen entièrement différent et beaucoup plus rapide d'effectuer la pagination en SQL. Ceci est souvent appelé la "méthode de recherche" ou la "pagination par jeu de clés" comme décrit dans cet article de blog ici .
Le "prédicat de recherche"
Les valeurs
@previousScore
et@previousPlayerId
sont les valeurs respectives du dernier enregistrement de la page précédente. Cela vous permet de récupérer la page "suivante". Si laORDER BY
direction estASC
, utilisez simplement à la>
place.Avec la méthode ci-dessus, vous ne pouvez pas passer immédiatement à la page 4 sans avoir d'abord récupéré les 40 enregistrements précédents. Mais souvent, vous ne voulez pas sauter aussi loin de toute façon. Au lieu de cela, vous obtenez une requête beaucoup plus rapide qui peut être en mesure de récupérer des données en temps constant, en fonction de votre indexation. De plus, vos pages restent "stables", peu importe si les données sous-jacentes changent (par exemple à la page 1, pendant que vous êtes à la page 4).
C'est le meilleur moyen d'implémenter la pagination lors du chargement paresseux de données supplémentaires dans des applications Web, par exemple.
Notez que la "méthode de recherche" est également appelée pagination du jeu de clés .
Nombre total d'enregistrements avant la pagination
La
COUNT(*) OVER()
fonction de fenêtre vous aidera à compter le nombre total d'enregistrements "avant la pagination". Si vous utilisez SQL Server 2000, vous devrez recourir à deux requêtes pour leCOUNT(*)
.la source
OFFSET .. FETCH
ou avec desROW_NUMBER()
astuces précédentes .RowNumber
me donne 10 éléments cohérents par page. [3] cela ne fonctionne pas avec les grilles existantes qui supposentpagenumber
etpagesize
.À partir de SQL Server 2012, nous pouvons utiliser
OFFSET
etFETCH NEXT
Clause pour réaliser la pagination.Essayez ceci, pour SQL Server:
TechNet: pagination d'une requête avec SQL Server
la source
MSDN: ROW_NUMBER (Transact-SQL)
la source
Il existe un bon aperçu des différentes techniques de pagination sur http://www.codeproject.com/KB/aspnet/PagingLarge.aspx
J'ai utilisé la méthode ROWCOUNT assez souvent, principalement avec SQL Server 2000 (fonctionnera également avec 2005 et 2008, il suffit de mesurer les performances par rapport à ROW_NUMBER), c'est rapide comme l'éclair, mais vous devez vous assurer que les colonnes triées ont (principalement ) des valeurs uniques.
la source
Pour SQL Server 2000, vous pouvez simuler ROW_NUMBER () à l'aide d'une variable de table avec une colonne IDENTITY:
Cette approche peut être étendue aux tables avec des clés multi-colonnes, et elle n'entraîne pas la surcharge de performances de l'utilisation de OR (qui ignore l'utilisation de l'index). L'inconvénient est la quantité d'espace temporaire utilisée si l'ensemble de données est très volumineux et que l'on se trouve près de la dernière page. Je n'ai pas testé les performances du curseur dans ce cas, mais cela pourrait être mieux.
Notez que cette approche pourrait être optimisée pour la première page de données. En outre, ROWCOUNT a été utilisé car TOP n'accepte pas de variable dans SQL Server 2000.
la source
La meilleure façon de paginer dans SQL Server 2012 est d'utiliser le décalage et la récupération suivante dans une procédure stockée. Mot - clé OFFSET - Si nous utilisons offset avec la clause order by, la requête ignorera le nombre d'enregistrements que nous avons spécifié dans OFFSET n Rows.
Mots - clés FETCH NEXT - Lorsque nous utilisons Fetch Next uniquement avec une clause order by, il renvoie le nombre de lignes que vous souhaitez afficher dans la pagination, sans décalage, puis SQL génère une erreur. voici l'exemple donné ci-dessous.
vous pouvez l'exécuter comme suit.
la source
Ce sont mes solutions pour paginer le résultat d'une requête côté serveur SQL. ces approches sont différentes entre SQL Server 2008 et 2012. De plus, j'ai ajouté le concept de filtrage et de tri par une seule colonne. Il est très efficace lorsque vous effectuez une recherche, un filtrage et une commande dans votre Gridview.
Avant de tester, vous devez créer un exemple de table et insérer une ligne dans ce tableau: (Dans le monde réel, vous devez modifier la clause Where en tenant compte des champs de votre table et peut-être avez-vous une jointure et une sous-requête dans la partie principale de select)
Dans tous ces exemples, je souhaite interroger 200 lignes par page et je récupère la ligne pour le numéro de page 1200.
Dans SQL Server 2008, vous pouvez utiliser le concept CTE. Pour cette raison, j'ai écrit deux types de requêtes pour SQL Server 2008+
- SQL Server 2008+
Et deuxième solution avec CTE dans SQL Server 2008+
- SQL Server 2012+
la source
Essayez cette approche:
la source
Dans le cas d'utilisation, les éléments suivants semblent faciles à utiliser et rapides. Définissez simplement le numéro de page.
également sans CTE
la source
Eh bien, j'ai utilisé l'exemple de requête suivant dans ma base de données SQL 2000, cela fonctionne bien pour SQL 2005 aussi. La puissance qu'il vous donne est dynamiquement ordonnée en utilisant plusieurs colonnes. Je vous le dis ... c'est puissant :)
La meilleure partie est que sp_executesql met en cache les appels ultérieurs, à condition de transmettre les mêmes paramètres, c'est-à-dire de générer le même texte SQL.
la source
redémarrera idx en ce qui concerne les différents init_id
la source
Pour la
ROW_NUMBER
technique, si vous n'avez pas de colonne de tri à utiliser, vous pouvez utiliser les élémentsCURRENT_TIMESTAMP
suivants:Cela a bien fonctionné pour moi pour les recherches sur des tailles de table allant jusqu'à 700 000.
Cela récupère les enregistrements 11 à 30.
la source
la source
Ce bit vous donne la possibilité de paginer à l'aide de SQL Server et des versions plus récentes de MySQL et porte le nombre total de lignes dans chaque ligne. Utilise votre clé pimary pour compter le nombre de lignes uniques.
la source
Ceci est un double de l'ancienne question SO 2012: un moyen efficace de mettre en œuvre la pagination
Ici, le sujet est discuté plus en détail et avec des approches alternatives.
la source
À partir de 2012, nous pouvons utiliser
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
la source
Vous n'avez pas spécifié la langue ni le pilote que vous utilisez. Je le décris donc de manière abstraite.
la source