Comment Faire en Sorte Que SQL Server Agisse Comme Un Humain En Utilisant WAITFOR
Photo de Fischer Twins sur Unsplash
Vous accordez probablement vos requêtes pour des performances maximales. Vous êtes fier de savoir comment ajouter des index et du code de refactorisation afin d’éliminer chaque dernière goutte du potentiel de performance de votre serveur. La vitesse est généralement roi.
C’est pourquoi vous n’utilisez probablement pas régulièrement la commande WAITFOR de SQL Server – cela ralentit l’exécution de votre requête globale.
Cependant, la lenteur n’est pas toujours une mauvaise chose. Aujourd’hui, je veux vous montrer deux de mes façons préférées d’utiliser la commande WAITFOR.
Regardez la vidéo de cette semaine sur YouTube
Vous pouvez également regarder le contenu de cette semaine sur ma chaîne YouTube.
1. Construire un humain
Les ordinateurs modernes sont rapides. Les PROCESSEURS effectuent des milliards d’actions par seconde, la quantité de RAM fabriquée peut s’entasser sur un stick augmente régulièrement et les SSD font rapidement des problèmes d’E / S de disque une chose du passé.
Bien que toutes ces choses soient idéales pour traiter de grandes charges de travail, elles éloignent de plus en plus les ordinateurs de la « vitesse humaine ».
Mais la « vitesse humaine » est parfois ce que vous voulez. Vous souhaitez peut-être simuler l’utilisation de l’application sur votre base de données ou la charge créée par les analystes exécutant des requêtes ad hoc sur votre serveur.
C’est là que j’aime utiliser WAITFOR DELAY – il peut simuler des humains exécutant des requêtes extrêmement bien:
-- Run foreverWHILE (1=1)BEGIN --Insert data to simulate an app action from our app EXEC dbo.BuyDonuts 12 -- We usually average an order every 3 seconds WAITFOR DELAY '00:00:03'END
Ajoutez une génération de nombres psuedo-aléatoires et des instructions IF, et vous avez une fausse charge de serveur que vous pouvez commencer à utiliser:
WHILE (1=1)BEGIN -- Generate command values 1-24 DECLARE @RandomDonutAmount int = ABS(CHECKSUM(NEWID()) % 25) + 1 -- Generate a delay between 0 and 5 seconds DECLARE @RandomDelay int = ABS(CHECKSUM(NEWID()) % 6) EXEC dbo.BuyDonuts @RandomDonutAmount WAITFOR DELAY @RandomDelayEND
2. Le courtier de service du pauvre
Le courtier de service est une excellente fonctionnalité de SQL Server. Il gère très bien les scénarios de messagerie et de file d’attente, mais nécessite plus de temps de configuration, donc je n’aime généralement pas l’utiliser dans des scénarios où j’ai besoin de quelque chose de rapide et sale.
Au lieu d’avoir à configurer Service Broker pour savoir quand certaines données sont disponibles ou qu’un processus est prêt à être lancé, je peux faire de même avec une boucle WHILE et un WAITFOR :
DECLARE @Quantity smallint = NULL-- Keep checking our table data until we find the data we wantWHILE (@Quantity IS NULL)BEGIN -- Delay each iteration of our loop for 10 seconds WAITFOR DELAY '00:00:03' -- Check to see if someone has bought a dozen donuts yet SELECT @Quantity = Quantity FROM dbo.Orders WHERE Quantity = 12END-- Run some other query now that our dozen donut purchase condition has been metEXEC dbo.GenerateCoupon
Envie? Aucun. Pratique ? Oui.
Je n’ai plus besoin de continuer à vérifier les résultats d’une table avant d’exécuter une requête – je peux avoir WAITFOR le faire pour moi.
Si vous savez qu’il y a un moment précis que vous souhaitez attendre jusqu’à ce que vous commenciez à lancer un processus, vous pouvez intégrer WAITFOR TIME pour rendre votre vérification encore plus intelligente:
DECLARE @Quantity smallint = NULL-- Let's not start checking until 6am...that's when the donut shop opensWAITFOR TIME '06:00:00'-- Keep checking our table data until we find the data we wantWHILE (@Quantity IS NULL)BEGIN -- Delay each iteration of our loop for 10 seconds WAITFOR DELAY '00:00:03' -- Check to see if someone has bought a dozen donuts yet SELECT @Quantity = Quantity FROM dbo.Orders WHERE Quantity = 12END-- Run some other query now that our dozen donut purchase condition has been metEXEC dbo.GenerateCoupon