Pagination dans deux tables dans SQL Server

J'ai deux tables,

  • Orders – ceci est petit, typiquement jusqu'à 50 milliers d'loggings
  • OrdersArchive – celui-ci est normal, environ 80 millions d'loggings

Cette situation pourrait arriver:

l'ordre peut avoir une de ces valeurs pour le status :

  1. 'créé'
  2. 'En traitement'
  3. 'fini'

Les commands terminées à partir des Orders sont périodiquement déplacées vers OrdersArchive .

En d'autres termes, les Orders peuvent contenir des commands dont le statut est created , processing ou finished . OrdersArchive contient seulement les commands avec un statut de finished .

Le résultat doit être sortingé dans cet ordre 'créé', 'traitement', 'fini'

J'ai besoin d'une requête dans ces deux tables qui supporte la pagination.

Quelle est la meilleure façon de le faire? (aussi vite que possible)

Une pagination peut être de n'importe quel type

Je veux dire:

  • la pagination classique avec PageNumber et CountOfRowsPerPage.
  • pagination «paresseuse» avec le count des ordres après l'ordre spécifique.

J'utiliserais l'opérateur SQL union pour cela. Voir la page w3schools pour plus de détails.

Avec le syndicat, vous pouvez soit faire du union ou du union all . Le premier vérifiera les duplicates alors que le second ne fera que combiner les résultats. Il semble que vous ne devriez pas avoir de duplicates dans ces deux arrays, donc pour la performance, vous n'avez pas besoin de faire la search distincte.

Vous devez également vous assurer que les deux requêtes ont le même nombre de colonnes avec des types similaires.

par exemple

 select orderno, status from Orders union all select orderno, status from OrdersArchive order by status, orderno 

Pagination
Cette requête vous donne le résultat combiné pour les deux tables. Maintenant, pour append une pagination, j'utiliserais un CTE avec des numéros de ligne comme ceci:

 with x as ( select orderno as num, status as stat from Orders union all select archiveorderno as num, archivestatus as stat from OrdersArchive ) select row_number() over(order by stat, num) as rownum, num, stat from x where rownum between 1 and 20 

Alternative
Si vous trouvez que l'utilisation de l'union est trop lente, vous pouvez changer la façon dont votre search fonctionne. Si vous sortingez toujours de la même manière et que les loggings sont toujours issus des commands suivies des loggings de OrdersArchive, vous pouvez interroger les tables séparément. Commencez par paginer à travers les commands, puis lorsque vous n'avez plus d'loggings, continuez à paginer via OrdersArchive. Ce serait beaucoup plus rapide que l'union, mais vous devez garder la requête simple et toujours sortinger le statut. L'union permet des searchs beaucoup plus complexes.

L'utilisation de OFFSET et FETCH NEXT dans SQL Server peut fournir une solution de pagination. Le code de l'échantillon brut est:

 DECLARE @PageNumber INT = 2 DECLARE @PageSize INT = 100000; SELECT [ID] FROM [Table] ORDER BY [ID] OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY 

De toute évidence, placez-le dans vos propres tables, filters, commands et placez-le probablement dans une procédure stockée avec les parameters d'input PageNumber et PageSize.