2017-05-22 5 views
2

Ich habe versucht, die folgenden Abfragen, um eine Ergebnismenge zurück zu übertreffen Excel mit ADO.Optimierung der SQL-ADO-Rückgabezeit

MAX

SELECT DISTINCT Term 
FROM uSubjectivities 
WHERE account_no = '1172014' 
    AND version_num = (SELECT max(Cast(version_num as Int)) from uSubjectivities 
          WHERE account_no='1172014' 
           AND SubjectivityID = '6472140') 
     AND SubjectivityID = '6472140' 
     AND TermType = 'Common' 

TOP (1)

SELECT DISTINCT Term 
FROM uSubjectivities 
WHERE account_no = '1172014' 
    AND version_num = (SELECT TOP (1) Cast(version_num as Int) 
         FROM uSubjectivities 
         WHERE account_no='1172014' 
          AND SubjectivityID = '6472140' 
         ORDER BY version_num DESC) 
    AND SubjectivityID = '6472140' 
    AND TermType = 'Common' 

UPDATE JOIN

SELECT DISTINCT Term 
FROM uSubjectivities S 
INNER JOIN 
(
    SELECT TOP (1) Cast(version_num as Int) v 
    FROM uSubjectivities 
    WHERE account_no='1172014' 
     And SubjectivityID = '6472140' 
    ORDER BY version_num DESC 
) mv 
ON mv.v = s.version_num 
WHERE SubjectivityID = '6472140' 
    AND TermType = 'Common' 

Beide benötigen jedoch viel länger als ich (und meine Benutzer) möchte.

Max dauert 14 Sekunden, um 15 Datensätze zurückzugeben (Typ ist varchar (max), da dies Felder mit langen Textzeichenfolgen sein können). Top 1 dauert 14 Sekunden. Join dauert 16 Sekunden

Jeder Parameter in einfachen Anführungszeichen wird letztlich in die Abfrage übergeben. Ich führe die Abfrage ungefähr 6 mal durch (könnte aber mehr oder weniger von Parametern abhängen). In meinem Beispiel dauert dieser Teil des Codes jetzt 42 Sekunden auf Max und 37 auf Top 1. 40 Sekunden für Join.

Gibt es sowieso, um diese Geschwindigkeit zu optimieren. Momentan versuchen wir, Indexierung zu vermeiden, da die Datenbank immer wieder neu indiziert werden muss.

Darüber hinaus laufen beide Abfragen in Nanosekunden innerhalb von SQLServer, so dass ich nicht weiß, warum sie in ADO so langsam sind.

EDIT Ich habe auch dies in einer gespeicherten Prozedur und rief wie dies auch von VBA geladen. Hat bei der Rückkehr nicht geholfen.

+0

Vielleicht die Abfragen innerhalb der SS Speicherung Ihrer Verarbeitung, da als gespeicherte SS Objekte beschleunigen, werden sie optimiert werden - nur in den Parametern übergeben, wie gebraucht. – flaZer

+0

Vergewissern Sie sich außerdem, dass Sie der "beste" Treiber zum Abrufen Ihrer Daten sind. Verwenden Sie nach Möglichkeit lieber native SQL SERVER-Treiber als die generischen ODBC-Treiber. – flaZer

+0

Oh yeah eine andere Sache ... über diese Nanosekunden Ergebnis in SS ... sei sicher in MGMT STUDIO, dass die "volle" Ergebnismenge in Nanosekunden zurückgekehrt ist. Es ist durchaus möglich, dass Ihr Ergebnisfenster, obwohl es aussieht, als hätten Sie Ihre Ergebnisse, immer noch gefüllt ist. – flaZer

Antwort

0

Sie haben ein Problem namens korrelierte Unterabfrage:

In einer SQL-Datenbank-Abfrage, eine korrelierte Unterabfrage (auch als synchronisiert subquery bekannt) ist eine Unterabfrage (eine Abfrage innerhalb eines anderen Abfrage verschachtelt), dass verwendet Werte aus der äußeren Abfrage. Da die Unterabfrage für jede von der äußeren Abfrage verarbeitete Zeile einmal ausgewertet werden kann, kann sie ineffizient sein.

sehen hier ein anderes Beispiel:

SELECT employee_number, name 
    FROM employees AS emp 
    WHERE salary > (
    SELECT AVG(salary) 
     FROM employees 
     WHERE department = emp.department); 

Um dies zu lösen, müssen Sie das Ergebnis stattdessen verbinden ein anderes wählen Sie in Ihrer ersten Auswahl zu tun, überprüfen Sie diese Antwort here

+0

Interessant, weil meine Unterabfrage stand-alone ausgeführt werden kann und unabhängig von der Außenabfrage ist. Ich teste gerade die Verbindung aus, um zu sehen, ob es hilft. –

+0

schreiben es als ein Join hinzugefügt 3 Sekunden auf die gesamte Laufzeit :( –

+0

Konnte ich die Abfrage mit Join sehen? –

1

Sie können versuchen, immer los von der Unterabfrage und verwenden Sie eine Bestellung von oben in Ihrer Hauptauswahl:

SELECT TOP 1 Term 
FROM uSubjectivities 
WHERE account_no = '1172014' 
AND SubjectivityID = '6472140' 
AND TermType = 'Common' 
ORDER BY version_num desc 

Hier ist eine weitere Option für n Reihen:

SELECT Term 
FROM (SELECT Term, 
      RANK() over (ORDER BY version_num desc) AS RK 
     FROM uSubjectivities 
     WHERE account_no = '1172014' 
     AND SubjectivityID = '6472140' 
     AND TermType = 'Common') A 
WHERE RK = 1 
+0

dachte ich auch, aber ich muss die * n * Zeilen pro zurückgeben Die letzte Versionsnummer –

+0

Das stimmt auch, es ist ein guter Weg! –

+0

@ScottHoltzman Übersehen das, fügte einen anderen Weg hinzu .. Seitliche Anmerkung, Es scheint ziemlich klar, dass ADO sich schlecht verhält, da Ihre Abfragen in Ordnung sind, wie Sie sie haben es wird 'RANK()' besser behandeln, aber das kann ein hoffnungsvoller Gedanke sein. –