8
votes

Quertise pour le nombre maximum de couvre-temps simultanés

J'ai une table SQL Server avec deux champs DateTime ( cnxstartDateTetime code>, cnxenddationtime code>). Chaque ligne représente une transmission d'informations. J'essaie de trouver le nombre maximum de transmissions simultanées en fonction de ces deux horodatages forts>. J'ai une requête de travail mais c'est à la fois lent et extrêmement lourd. Je sais qu'il doit y avoir une meilleure façon d'y aller, mais je ne peux pas venir avec aucun.

Pour la version actuelle, si je l'exécute avec 5 "niveaux" et obtenez des résultats que je dois revenir en arrière et ajouter une tonne de SQL à tester s'il y a des instances de 6 transmissions simultanées, etc. Une fois que la requête obtient 7-8 "niveaux" profondément, cela devient très lent. p>

extrait de la version actuelle: p>

A         [--------]
B    [-----]
C              [------]
D   [---]
E             [---]
F         [-]


5 Réponses :


1
votes

Jeff. J'ai écrit une requête similaire une fois - mais à Oracle - je ne sais pas si cela fonctionnera dans SQL-Server, mais cela vaut la peine d'essayer: peut-être que cela vous donnera une idée:

select
  t.time as b,
  lead(t.time)  over (order by t.time, t.weight desc) as e,
  sum(t.weight) over (order by t.time, t.weight desc) as cnt
from
  ( select trunc(:aStartWith)   as time,  0 as weight from dual
    union all
    select req_recieved as time, +1 as weight
      from log_tbl
      where trunc(req_recieved, 'mi') between :aStartWith - interval '10' minute and :aEndWith + interval '10' minute
    union all
    select response_sent as time, -1 as weight
      from log_tbl
      where trunc(req_recieved, 'mi') between :aStartWith - interval '10' minute and :aEndWith + interval '10' minute
    union all
    select trunc(:aEndWith) as time,  0 as weight from dual
  ) t


1 commentaires

Ceci est donc basé sur le passage par paires d'horodatages représentant des effectifs de temps pour vérifier le nombre de demandes survenant dans la durée de l'heure? Étant donné que le calendrier des demandes de démarrage / fin dépasse à la milliseconde, comment suis-je supposé être supposé que toutes les paires appropriées d'horodatages de début / de fin doivent être passées? Je pourrais être confondu sur la façon dont votre solution fonctionne.



0
votes

C'est plutôt une solution de rapport que la requête de base de données "standard". Meilleure option pour cela consiste à écrire une quantité de transactions quelque part au début de chaque transaction). Toutes les autres solutions seront lentes. Mais si vous avez vraiment besoin de cela ...

La solution la plus simple consiste à scinder la durée des petites pièces (par exemple jours) et d'analyser les comptes dans chaque période. Voici un exemple: xxx

Vous pouvez modifier la dernière instruction pour obtenir des informations nécessaires (transactions dans la période de chargement maximale, etc.)


1 commentaires

Je reçois le sentiment que cette approche a le même problème que l'ANDR en ce que les horodatages dont je parle diffèrent de millisecondes tandis que votre approche exige que je concocte des périodes de temps couvrant tous les scénarios possibles. Ou suis-je mal compris comment cela fonctionne?



1
votes
ID          Starts                  Ends
----------- ----------------------- -----------------------
2           2001-01-01 00:00:00.000 2001-01-10 00:00:00.000
3           2001-01-02 00:00:00.000 2001-01-05 00:00:00.000
4           2001-01-03 00:00:00.000 2001-01-04 00:00:00.000

2 commentaires

J'ai ajouté des informations à la question pour montrer comment ce n'est pas tout ce que je cherche.


@Jeff a ajouté une autre version. Ce n'est pas la croix rejoindre qui est à blâmer, c'est la clause WHERE. Je suppose que le duplicate suggéré de Martin est ce que vous voulez. La différence entre cela et mon changement est que lorsque vous utilisez entre est que entre est inclusif. Cette version compte les niveaux simultanés maximum au lieu de couvre-vêtements de chevauchement total.



0
votes
/* remove the sample data (unless it's your table) */
DROP TABLE MyTable

0 commentaires

0
votes

Je sais que les curseurs sont fronça les sourcils, mais les jointures croisées. Ce retour 8 code> pour les données d'échantillonnage fournies.

-- assuming times table with columns s and e
declare @s datetime, @e datetime;
declare @t table(d datetime);
declare c cursor for select s,e from times order by s;
open c
while(1=1) begin
  fetch next from c into @s,@e
  if @@FETCH_STATUS<>0 break;
  update top(1) @t set d=@e where d<=@s;
  if @@ROWCOUNT=0 insert @t(d) values(@e);
end
close c
deallocate c

select COUNT(*) as MaxConcurrentTimeSpans from @t


0 commentaires