La table se compose des colonnes calling_party et called_party et l'enregistrement décrit la connexion entre deux utilisateurs où l'un joue un rôle d'appelant et l'autre est appelé party.Une suggestion pour optimiser la requête suivante qui compte commun et tous les voisins?
Les deux mêmes utilisateurs peuvent avoir deux connexions - dans ce cas, les rôles appelant/appelé sont activés lorsque la direction est modifiée.
Dans la table d'origine (monthly_connections), j'ai ajouté des colonnes supplémentaires common_neighbors et total_neighbors où le nombre de voisins communs et totaux est stocké. Pour clarifier les termes communs et je total_neighbors ajouté l'image suivante:
Dans ce cas pour la connexion observée il y a 2 communes voisines d'appelant et l'appelé et 6 voisins au total.
Afin d'obtenir ces deux valeurs que j'écrit la procédure stockée suivante:
CREATE PROCEDURE [dbo].[spCountNeighbors]
AS
Declare
@CallingParty varchar(50),
@CalledParty varchar(50),
@RecordsUpdated int
SET @CallingParty ='a'
SET @RecordsUpdated = 0
PRINT GETDATE()
WHILE @CallingParty IS NOT NULL BEGIN
SET @CallingParty = NULL
SELECT TOP 1 @CallingParty = calling_party, @CalledParty = called_party FROM monthly_connections WHERE common_neighbors IS NULL
--PRINT @CallingParty
IF @CallingParty IS NOT NULL BEGIN
WITH callingPartyNeighbors AS
(
SELECT called_party as neighbor FROM monthly_connections WHERE calling_party = @CallingParty
UNION
SELECT calling_party as neighbor FROM monthly_connections WHERE called_party = @CallingParty
),
calledPartyNeighbors AS
(
SELECT calling_party as neighbor FROM monthly_connections WHERE called_party = @CalledParty
UNION
SELECT called_party as neighbor FROM monthly_connections WHERE calling_party = @CalledParty
)
UPDATE mc SET common_neighbors = (SELECT COUNT (*) FROM
(
SELECT neighbor FROM callingPartyNeighbors
INTERSECT
SELECT neighbor FROM calledPartyNeighbors
)
t1
),
total_neighbors = (SELECT COUNT (*) FROM
(
SELECT neighbor FROM callingPartyNeighbors
UNION
SELECT neighbor FROM calledPartyNeighbors
)
t2
)
FROM monthly_connections mc WHERE (mc.calling_party = @CallingParty AND mc.called_party = @CalledParty) OR (mc.called_party = @CallingParty AND mc.calling_party = @CalledParty);
SET @RecordsUpdated = @RecordsUpdated + @@ROWCOUNT
PRINT @RecordsUpdated
END
END
PRINT @RecordsUpdated
La procédure ci-dessus est censé passer par la table des connexions qui contient des connexions 23m et mettre à jour les valeurs common_neighbors et total_neighbors pour chaque ligne . Le problème est cependant que la procédure est trop lente - il a fallu 212 s pour mettre à jour 1000 enregistrements.
Je serais vraiment reconnaissant si quelqu'un d'entre vous a suggéré une solution pour la procédure ci-dessus afin d'accélérer le temps d'exécution.
Merci!