Si la performance est votre préoccupation, ont cette UDF prêt:
create function [dbo].[Numbers](@count bigint)
RETURNS TABLE RETURN
with byte (n) as (select 1 from (VALUES
(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
) x(n) )
, byte2 (n) as (select 1 from byte a, byte b)
, byte4 (n) as (select 1 from byte2 a, byte2 b)
, byte8 (n) as (select 1 from byte4 a, byte4 b)
select top(@count) n = ROW_NUMBER() over(order by n) from byte8
Apparemment, généré fonctionne séquence de nombres récursivité uniquement CTE, mais très lent. Ici, nous échangeons du volume de code pour une augmentation énorme des performances. Celui-ci me donne plus de 30 millions de numéros en 8 secondes sur mon PC surchargé. Il peut aller aussi loin que vous le voulez et vous pouvez vous permettre la limite de max bigint.
Il ne touchera pas l'E/S du disque à moins que l'optimiseur l'exclue de la mémoire (rarement pour un scénario raisonnable). Cela évitera également les attentes et les interblocages, contrairement aux solutions basées sur des tables physiques.
Utilisez comme ceci:
select 2 + n*5 from Numbers(100)
Vous devriez être en mesure de créer une vue comme celui-ci.
Pour ceux qui n'ont pas besoin d'un nombre réel, juste des lignes, en supprimant le nombre row_number l'accélère deux fois.
Inspiré par http://weblogs.sqlteam.com/jamesn/archive/2008/05/29/60612.aspx (Itzik Ben Gan mentionné par S. Neumann). Cette version est livrée avec un plan d'exécution plus simple et rend les bigints possibles, c'est à propos des avantages.
Y at-il une raison de le faire en SQL plutôt qu'au niveau de l'application? – Borealid
@Borealid - Il est souvent utile d'avoir une table de nombres auxiliaires en SQL. –
@Borealid: Si je pouvais générer une telle table, alors je crois que je pourrais l'utiliser pour construire des requêtes plus compliquées; Si je l'ai généré dans l'application, je pense que je serais coincé avec des instructions SQL super longues avec la séquence intégrée en eux. –