Oui c'est une des solutions que je cite dans mon premier message, mais que je fasse ma boucle du coté client ou sql, c'est très certainement plus lent que mon select * from numero where not exists (select 1 .....) and num < (select max(....))
J'en mettrai pas ma main à couper !
Je ne crois que les chiffres : exécutez les deux requêtes avec les options de session SET STATISTICS IO ON et SET STATISTICS TIME ON, puis comparez.
Solution qui a été choisie pour le moment (pas par moi) et qui me déplait est de créer une table avec des millions d'enregistrement et de faire un exists sur la table que l'on veut vérifier et notre table de numéro.
Cette table peut vous permettre de rendre votre requête très performante, comme une table de dates.
Ce sont des tables qui n'ont rien à faire d'un schéma (bon, et alors ?) mais qui peuvent s'avérer être très utiles : il vous suffit d'écrire une requête avec le prédicat EXCEPT et le tour est joué !
Vous avez alors une requête ensembliste, un temps d'exécution correct.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| -- Table des nombres de 0 à 100
CREATE TABLE TbNombres
(
nombre INT
)
DECLARE @i INT SET @i = 1
WHILE @i <= 100
BEGIN
INSERT INTO dbo.TbNombres VALUES (@i)
SET @i = @i + 1
END
-- Talbe représentant la requête extrayant les nombres
CREATE TABLE TbValeurs
(
valeur INT
)
INSERT INTO dbo.TbValeurs VALUES(1)
INSERT INTO dbo.TbValeurs VALUES(2)
INSERT INTO dbo.TbValeurs VALUES(4)
INSERT INTO dbo.TbValeurs VALUES(5)
INSERT INTO dbo.TbValeurs VALUES(8)
INSERT INTO dbo.TbValeurs VALUES(20)
INSERT INTO dbo.TbValeurs VALUES(21)
INSERT INTO dbo.TbValeurs VALUES(22)
GO
-- Requête finale
SELECT nombre
FROM dbo.TbNombres N
JOIN dbo.TbValeurs V ON N.Nombre <= V.Valeur
EXCEPT
SELECT valeur
FROM dbo.TbValeurs |
c'est lent pour faire pareil
Vrai
je gagne juste de la place dans ma db
Une table temporaire est .. une table et est donc stockée en tant que telle dans la base de données TempDB, dont SQL Server se sert massivement pour bien d'autres choses ...
Conséquence : si votre table temporaire est une # ou ##, vous demandez à SQL Server de maintenir des statistiques en plus de celles qu'il maintient dans les autres bases, de faire grossir le fichier, ...
Pour vous en convaincre, créez une table ou une variable de type table, sans même la peupler, et regardez la node "Tables temporaires" de TempDB :
1 2 3 4 5 6
| DECLARE @TbToto TABLE
(
val INT
)
WAITFOR DELAY '00:00:10' |
Puis
CREATE TABLE #TOTO (val INT)
Si votre table temporaire est en fait une variable de type TABLE, elle est toujours stockée en tant que telle dans TempDB, mais SQL Server ne maintient aucune statistique, donc si elle contient beaucoup de lignes (et pire, de colonnes), bonjour les dégâts chez les performances.
C'est un problème pourtant tellement élémentaire que j'ai honte de ne pas trouver.
Quelle honte y-a-t-il ? tous les problèmes ne sont pas simples.
Le problème des non-équi-jointures est un problème récurrent 
@++
Partager