Die Tabelle besteht aus den Spalten Calling_party und Called_party und der Datensatz beschreibt die Verbindung zwischen zwei Benutzern, wobei einer die Rolle des rufenden Teilnehmers spielt und der andere Teilnehmer heißt.Irgendwelche Vorschläge zur Optimierung der folgenden Abfrage, die gemeinsam und alle Nachbarn zählt?
Die gleichen zwei Benutzer können zwei Verbindungen haben - in diesem Fall werden die Rollen rufender/angerufener Teilnehmer umgeschaltet, wenn die Richtung geändert wird.
In der ursprünglichen Tabelle (Monatsverbindungen) habe ich zusätzliche Spalten common_neighbors und total_neighbors hinzugefügt, in denen die Anzahl der gemeinsamen und gesamten Nachbarn gespeichert sind. Um zu klären, werden die Begriffe häufig und total_neighbors Ich habe folgendes Bild:
In diesem Fall für die beobachtete Verbindung gibt es zwei gemeinsame Nachbarn des Anrufers und Angerufenen und insgesamt 6 Nachbarn.
Um diese beiden Werte zu erhalten, schrieb ich die folgende gespeicherte Prozedur:
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
Das Verfahren oben soll durch die Tabelle von Verbindungen gehen, die für jede Zeile 23M Verbindungen und Aktualisierungswerte common_neighbors und total_neighbors enthält . Das Problem ist jedoch, dass die Prozedur zu langsam ist - es dauerte 212 s, um 1000 Datensätze zu aktualisieren.
Ich würde mich sehr freuen, wenn jemand von Ihnen eine Lösung für das obige Verfahren vorschlagen würde, um die Ausführungszeit zu beschleunigen.
Vielen Dank!