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
:
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:
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.