Zugriff von SQL Server 2012 auf Intersystems Cache DB - Abfrage dauert ewig bzw. bring keine Ergebnisse
Moin liebe Admins,
ich habe mal wieder eine Frage.
Wie oben schon genannt starte ich eine Abfrage von SQL Server aus:
Es ist eine insert into select abfrage die über einen Verbindungsserver auf eine Cache DB zugreift.
Dabei werden zwei Cache Tabellen gejoint.
Das Ergebnis der Abfrage soll die Daten in eine vorhandene SQL Server Tabelle wegschreiben.
Leider dauert es sooo lange, dass ich sie schon abbreche bevor sie Daten liefert. Habe auch schon 2 Stunden gewartet.
Weiß einer eine Lösung wie man so eine Abfrage beschleunigen kann oder wie sie gestaltet werden muss?
Gibt es eigentlich noch eine andere Lösung als über einen Verbindungsserver zu gehen ähnlich wie die verlinkten Tabellen wie in Access?
Bin für alle Antworten dankbar.
Gruss DerO
ich habe mal wieder eine Frage.
Wie oben schon genannt starte ich eine Abfrage von SQL Server aus:
Es ist eine insert into select abfrage die über einen Verbindungsserver auf eine Cache DB zugreift.
Dabei werden zwei Cache Tabellen gejoint.
Das Ergebnis der Abfrage soll die Daten in eine vorhandene SQL Server Tabelle wegschreiben.
Leider dauert es sooo lange, dass ich sie schon abbreche bevor sie Daten liefert. Habe auch schon 2 Stunden gewartet.
Weiß einer eine Lösung wie man so eine Abfrage beschleunigen kann oder wie sie gestaltet werden muss?
Gibt es eigentlich noch eine andere Lösung als über einen Verbindungsserver zu gehen ähnlich wie die verlinkten Tabellen wie in Access?
Bin für alle Antworten dankbar.
Gruss DerO
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 211199
Url: https://administrator.de/contentid/211199
Ausgedruckt am: 22.11.2024 um 19:11 Uhr
21 Kommentare
Neuester Kommentar
Hallo,
vielleicht versuchst du mal folgendes:
Select * into #tbl1 from cache table 1
Select * into #tbl2 from cache table 2
Insert into select .. from #tbl1 <join> #tbl2
drop table #tbl1
drop table #tbl2
Also quasi ein Ansatz, zunächst die Tabellen 1zu1 physisch oder in TempDB als temporäre tabellen zu übernehmen. Im Anschluss die Query aufsetzen (evt. indizes setzen, je nach Performance und dann ausführen.
Das Wiederherstellungsmodell würde ich zuvor auf "simple" setzen, damit das Transaktionsprotokoll nicht voll läuft.
Das ist aber alles mehr oder weniger Glaskugel, da keinerlei Infos zu Datenmenge, Hardware und Verbindungsdetails (Wan, Lan) bekannt sind.
Gruss
Grinskeks
vielleicht versuchst du mal folgendes:
Select * into #tbl1 from cache table 1
Select * into #tbl2 from cache table 2
Insert into select .. from #tbl1 <join> #tbl2
drop table #tbl1
drop table #tbl2
Also quasi ein Ansatz, zunächst die Tabellen 1zu1 physisch oder in TempDB als temporäre tabellen zu übernehmen. Im Anschluss die Query aufsetzen (evt. indizes setzen, je nach Performance und dann ausführen.
Das Wiederherstellungsmodell würde ich zuvor auf "simple" setzen, damit das Transaktionsprotokoll nicht voll läuft.
Das ist aber alles mehr oder weniger Glaskugel, da keinerlei Infos zu Datenmenge, Hardware und Verbindungsdetails (Wan, Lan) bekannt sind.
Gruss
Grinskeks
Moin orauso,
genz sicher bin ich nicht, wo am ehesten für die Optimierung anzusetzen wäre, aber es scheint ja angebracht zu sein zu vermuten, dass auf den größeren Datenklumpen, die "Positionstabelle" ein Fullselert gemacht wird.
Dazu die Frage: was sind denn die "eigentlichen" fachlichen Schlüssel, über die die beiden Tabellen zusammenhängen sollten? Die beiden JOIN-Felder Lagernummer und Mandantenname scheinen es ja nicht zu sein.
Was ist den der identifizierende Schlüssel der "kopftabelle"? Sind da "Mandantname" und "Filliale" enthalten?
Und irgendwie geht bei dir - zumindest im geposteten Statement - etwas durcheinander.
Was oben in den ersten SELECT-Feldern "
SELECT ‘0’ + TABELLE1.Filiale" heisst, erscheint im (viel, viel zu langen!) Order by als " ‘0’ + TABELLE1.Bestellfiliale,".
Grüße
Biber
genz sicher bin ich nicht, wo am ehesten für die Optimierung anzusetzen wäre, aber es scheint ja angebracht zu sein zu vermuten, dass auf den größeren Datenklumpen, die "Positionstabelle" ein Fullselert gemacht wird.
Dazu die Frage: was sind denn die "eigentlichen" fachlichen Schlüssel, über die die beiden Tabellen zusammenhängen sollten? Die beiden JOIN-Felder Lagernummer und Mandantenname scheinen es ja nicht zu sein.
Was ist den der identifizierende Schlüssel der "kopftabelle"? Sind da "Mandantname" und "Filliale" enthalten?
Und irgendwie geht bei dir - zumindest im geposteten Statement - etwas durcheinander.
Was oben in den ersten SELECT-Feldern "
SELECT ‘0’ + TABELLE1.Filiale" heisst, erscheint im (viel, viel zu langen!) Order by als " ‘0’ + TABELLE1.Bestellfiliale,".
Grüße
Biber
Versuch mal bitte folgendes
Set statistics io on;
set statistics time on;
SELECT * into #Tabelle2
FROM OPENQUERY(<linked server>,
'SELECT <Hier die benötigten Felder von Tabelle 2 rein> FROM Tabelle2') T2
Select * from #Tabelle2
Drop #Tabelle2
Es ist wichtig, dass das komplette Statement innerhalb der Openquery steht damit der verbundene Server komplett remote arbeitet. Das Order by sollte da nicht drin stehen - das kostet ordentlich performance und der Tabelle ist es egal, in welcher Reihenfolge die Inserts erfolgen.
Gruss
Grinskeks
Set statistics io on;
set statistics time on;
SELECT * into #Tabelle2
FROM OPENQUERY(<linked server>,
'SELECT <Hier die benötigten Felder von Tabelle 2 rein> FROM Tabelle2') T2
Select * from #Tabelle2
Drop #Tabelle2
Es ist wichtig, dass das komplette Statement innerhalb der Openquery steht damit der verbundene Server komplett remote arbeitet. Das Order by sollte da nicht drin stehen - das kostet ordentlich performance und der Tabelle ist es egal, in welcher Reihenfolge die Inserts erfolgen.
Gruss
Grinskeks
Moin orausdo,
das kann doch nicht sein... bei der Laufzeit kannst du doch schneller die Datensätze mit einer Laubsäge neu erstellen.
Das interessiert mich langsam aber auch, was da warum schiefgeht...
Du holst dich letzten Endes, wenn ich das richtig zusammenfasse, aus einer lächerlichen Datenmenge von gesammt 60000 Positionsdaten viellecht ein Hundertsel (alle Positionen dieses Selects);
Das ist doch der eigentliche Rest der Positionsdaten, mit dem du joinen musst.
Wie viele Sätze werden bei dieser Unter-Abfrage geliefert und in welcher Zeit?
Oder geht das auch in die Grütze?
Grüße
Biber
das kann doch nicht sein... bei der Laufzeit kannst du doch schneller die Datensätze mit einer Laubsäge neu erstellen.
Das interessiert mich langsam aber auch, was da warum schiefgeht...
Du holst dich letzten Endes, wenn ich das richtig zusammenfasse, aus einer lächerlichen Datenmenge von gesammt 60000 Positionsdaten viellecht ein Hundertsel (alle Positionen dieses Selects);
SELECT * from Tabelle2 where
Mandantenname ='0' and Lagernummer in
( select distinct(lagernummer
FROM TABELLE1
WHERE (TABELLE1.Erfassungsdatum=’12.07.2013‘)
AND (TABELLE1.Mandantenname=‘0‘)
AND (TABELLE1.Bestelltext=‘Irgendein_Text‘)
)
Das ist doch der eigentliche Rest der Positionsdaten, mit dem du joinen musst.
Wie viele Sätze werden bei dieser Unter-Abfrage geliefert und in welcher Zeit?
Oder geht das auch in die Grütze?
Grüße
Biber
Moin orausdo,
das sind keine Antwortzeiten, das sind Lieferzeiten.
Per Bus, Rikscha oder Bollerwagen. Und Zeit zum einzeln vorsingen wäre ja auch noch.
Ist eventuell denn das "Erfassungsdatum" im Access ein Datumsfeld und wird es nur durch deinen Textparameter '12.07.2013' irrsinnnig zeitaufwendig zwangsgecastet?
Oder ist da (in Acceess) noch ein drittes "verbindendes Feld" zwischen Tabelle1 und Tabelle2 , z.B. ein Datumsfeld ,als "Beziehung" hinterlegt
Anders gefragt: "Mandantenname" '0' und "Lagernummer" können doch in Tabelle1 nicht der identifizierende Schlüssel sein - diese Kombination muss es doch jede Woche wieder geben, oder nicht?..
Also - mag sein, dass der Verbindungsserver Zeit frisst, und auch mit dem allerersten "SELECT INTO Ergebnis, aber in einer sortierten Reihenfolge" hast du dat Dingen sicher unnötig gequält - aber derartige Antwortzeiten können nicht sein. Selbst wenn du noch parallel irgendwelche DVDs brennst auf dem Server.
Ich warte mal auf den Grinsekrümel...
Grüße
Biber
das sind keine Antwortzeiten, das sind Lieferzeiten.
Hab die Unterabfrage mal ausgeführt.
Sie dauerte 06:47 min und ergab 7367 Datensätze.
In dieser Zeit könnte ich auch die 7367 Zeilen vom Bremer Hauptbahnhof bis auf meinen Balkon bringen lassen.Sie dauerte 06:47 min und ergab 7367 Datensätze.
Per Bus, Rikscha oder Bollerwagen. Und Zeit zum einzeln vorsingen wäre ja auch noch.
Ist eventuell denn das "Erfassungsdatum" im Access ein Datumsfeld und wird es nur durch deinen Textparameter '12.07.2013' irrsinnnig zeitaufwendig zwangsgecastet?
Oder ist da (in Acceess) noch ein drittes "verbindendes Feld" zwischen Tabelle1 und Tabelle2 , z.B. ein Datumsfeld ,als "Beziehung" hinterlegt
Anders gefragt: "Mandantenname" '0' und "Lagernummer" können doch in Tabelle1 nicht der identifizierende Schlüssel sein - diese Kombination muss es doch jede Woche wieder geben, oder nicht?..
Also - mag sein, dass der Verbindungsserver Zeit frisst, und auch mit dem allerersten "SELECT INTO Ergebnis, aber in einer sortierten Reihenfolge" hast du dat Dingen sicher unnötig gequält - aber derartige Antwortzeiten können nicht sein. Selbst wenn du noch parallel irgendwelche DVDs brennst auf dem Server.
Ich warte mal auf den Grinsekrümel...
Grüße
Biber
Hmm,
falls du bei deinen Queries immer nach dem Datum selected hast, solltest du dieses mal in eine Variable packen und als Datetime casten - nur zum Test.
Bringt das Query Tuning da nichts, dann
- versuchen wir etwas anderes: Linked Server Einstellungen checken
Setze mal
lazy schema validation on
und checke, ob collation compatible an ist.
Gruss
Grinskeks
falls du bei deinen Queries immer nach dem Datum selected hast, solltest du dieses mal in eine Variable packen und als Datetime casten - nur zum Test.
Bringt das Query Tuning da nichts, dann
- versuchen wir etwas anderes: Linked Server Einstellungen checken
Setze mal
lazy schema validation on
und checke, ob collation compatible an ist.
Gruss
Grinskeks
Moin orausdo,
bitte prüfe nochmal meine Rückfragen und deine ntworten darauf.
Du hattest geschrieben:
Das halte ich nach wie vor für unwahrscheinlich, dass der identifizierende Schlüssel in der "Kopftabelle" nur Mandantenname und Lagernummer beinhalten kann.
Dann darf doch - bei deiner Eingrenzund auf Mandantenname='0' nur ein Datensatz fü das Lager 4711 herausfallen, egal ob du Erfassungsdatum '12.07.2013' einschränkst oder nicht.
Und wenn als der verbindende Schlüssel in der Positionstabelle tatsächlich nur "Mandantenname+Lagernumme" wäre plus "Positionsnummer" als Differenzierungskriterium, dann macht das Statement natürlich immer einen Fullselct auese "große" Tabelle. Da sind doch dann aber auch Daten aus den Jahren 2010 bis 2012 dabei - das wird doch nirgends eingeschränkt.
Die Zusammenhänge sind mir nicht plausibel.
Wenn es tatsächlich so ist wie beschrieben, dass stelle doch mal einen (ggf. stilisierten) Beispielsatz für Mandanten'0' und Lagernummer 4711 und die dazugehörigen Positionsdaten zur Anschauung hier vor.
Grüße
Biber
bitte prüfe nochmal meine Rückfragen und deine ntworten darauf.
Du hattest geschrieben:
Der join läuft über die beiden Schlüsselfelder Lagernummer + Mandantename.
Diese sind auch in den Quelltabellen die Schlüssel.
Diese sind auch in den Quelltabellen die Schlüssel.
Das halte ich nach wie vor für unwahrscheinlich, dass der identifizierende Schlüssel in der "Kopftabelle" nur Mandantenname und Lagernummer beinhalten kann.
Dann darf doch - bei deiner Eingrenzund auf Mandantenname='0' nur ein Datensatz fü das Lager 4711 herausfallen, egal ob du Erfassungsdatum '12.07.2013' einschränkst oder nicht.
Und wenn als der verbindende Schlüssel in der Positionstabelle tatsächlich nur "Mandantenname+Lagernumme" wäre plus "Positionsnummer" als Differenzierungskriterium, dann macht das Statement natürlich immer einen Fullselct auese "große" Tabelle. Da sind doch dann aber auch Daten aus den Jahren 2010 bis 2012 dabei - das wird doch nirgends eingeschränkt.
Die Zusammenhänge sind mir nicht plausibel.
Wenn es tatsächlich so ist wie beschrieben, dass stelle doch mal einen (ggf. stilisierten) Beispielsatz für Mandanten'0' und Lagernummer 4711 und die dazugehörigen Positionsdaten zur Anschauung hier vor.
Grüße
Biber
Moin orausdo,
ein casten von Text (-> dein eingegebenes '11.07.2013' auf einen Date-Typ geht in meiner Erinnerung so:
Dieses an die Stelle setzen, wo heute der String '11.07.2013' steht, im Statement die ORDER BY-clause umweltgerecht entsorgen und testen.
Grüße
Biber
ein casten von Text (-> dein eingegebenes '11.07.2013' auf einen Date-Typ geht in meiner Erinnerung so:
convert(datetime, '11.07.2013', 104)
-- 104 ist das Datumsformat dd.mm.yyyyDieses an die Stelle setzen, wo heute der String '11.07.2013' steht, im Statement die ORDER BY-clause umweltgerecht entsorgen und testen.
Grüße
Biber
Moin orausdo,
ich stehe verständnislos davor - ist mir vollkommen unerklärlich, was da schiefläuft.
Wenn ich es richtig interpretiere, dann schickst du über ODBC eine Abfrage auf die 2 Tabellen dieser ACCESS-Datenbank; der zurückkommende Resultset soll in eine Ergebnistabelle auf dem (fragenden) SQLServer geschrieben werden.
Da kann eigentlich nur begrenzt viel schiefgehen.
Und da du ja auch grundsätzlich Daten retour bekommst, kann ich nicht den Treiber als ungeeignet verdächtigen.
Tut mir leid, ich muss passen bzw. die Antworten von anderen abwarten.
Derartig langsame Abfragen kenne ich - selbst im Zusammenhang mit ACCESS- nicht.
Sorry
Biber
ich stehe verständnislos davor - ist mir vollkommen unerklärlich, was da schiefläuft.
Wenn ich es richtig interpretiere, dann schickst du über ODBC eine Abfrage auf die 2 Tabellen dieser ACCESS-Datenbank; der zurückkommende Resultset soll in eine Ergebnistabelle auf dem (fragenden) SQLServer geschrieben werden.
Da kann eigentlich nur begrenzt viel schiefgehen.
Und da du ja auch grundsätzlich Daten retour bekommst, kann ich nicht den Treiber als ungeeignet verdächtigen.
Tut mir leid, ich muss passen bzw. die Antworten von anderen abwarten.
Derartig langsame Abfragen kenne ich - selbst im Zusammenhang mit ACCESS- nicht.
Sorry
Biber
Hallo,
ich könnte Wetten, dass der SQL Server keine Indizes "sieht" über ODBC und deswenge so langsam sind. Jet Datenbanken (Access etc.) sind in diesem Fall flotter.
Wird der aktuellste Treiber vom ftp Server von Intersystems cache verwendet?
Gibt es SecurityTools, Firewalls etc. die die Connection / Ports bzgl. Performance beeinträchtigen?
Gruss
Grinskeks
ich könnte Wetten, dass der SQL Server keine Indizes "sieht" über ODBC und deswenge so langsam sind. Jet Datenbanken (Access etc.) sind in diesem Fall flotter.
Wird der aktuellste Treiber vom ftp Server von Intersystems cache verwendet?
Gibt es SecurityTools, Firewalls etc. die die Connection / Ports bzgl. Performance beeinträchtigen?
Gruss
Grinskeks