anna85
Goto Top

Abfrage von großen Datenmengen

Ich habe eine risiege Menge von Daten, ca 1.000.000.
Die Tabelle ist einfach aufgebaut:
tab1
nummer, prodnr

Allerdings Spalte prodnr ist leer, muss durch tab 2 befüllt werden.

Zweite Tabelle ist auch einfach, besteht aus ca 70.000 Datensätze
tab1
nummer, prodnr

Allerdings in tab2 manchmal zu einem nummer mehrere prodnr vorkommen, wie:

1 abc
2 gdb
2 tata

also nummer 2 hat in diesem Fall 2 prodnr.

Mit Hilfe von einem Mann habe ich eine Abfrage gebastelt, indem ich die prod aus tab 2 zu tab1 befüllt werden. Erstemal soll Prod 1 importiert werden, dann prod 2, damit die Tabelle im Schluss so aussieht:
1 abc null
2 gdb  tata

Die Abfrage sieht so aus, die funktioniert (ich habe auf kleine Dateimenge ausprobiert), aber mit der Menge von Daten läuft seit über 2h und ist grade bei 1/3:

select 
	tab1.nummer as 'nummer',  
	
			prodnr.*   
				
FROM [tab1] 
			
cross apply (select IIF( prodnr].[zeile] = '1', [tab2].[nummer], Null  )   
			    	  from ( select [tab2].[nummer], [tab2].[prodnr], row_number() over (partition by [tab2].[prodnr] order by [tab2].[prodnr]) as zeile
				  from tab2 
				 where tab1.nummer=tab2.nummer
				  ) tab2
				  for xml path ('')  
				  ) tab2 (tab2)
				  where tab1.nummeris not null

Wie erwähnt, Abfrage funktioniert, aber warum dauert es so lange? Ich muss die Abfrage noch mal für '2' starten.
Ich werde für jede Antwort sehr dankbar.

Falls ich hier falsch bin, bitte mein Post nicht löschen, einfach mitteilen!

Lieben Dank!

Content-ID: 519026

Url: https://administrator.de/contentid/519026

Ausgedruckt am: 25.11.2024 um 17:11 Uhr

aqui
aqui 26.11.2019 um 15:52:39 Uhr
Goto Top
Falls ich hier falsch bin, bitte mein Post nicht löschen, einfach mitteilen!
Aus gutem Grund kann das KEINER hier sondern nur DU selber als Threadowner !
Für das fehlende "n" in der Überschrift und den Fauxpas bei riesig gibts immer den "Bearbeiten" Button hier. face-wink
Fennek11
Fennek11 26.11.2019 um 17:42:34 Uhr
Goto Top
versuche es mit Excel, genauer VBA: beide Tabellen in ein Array einlesen und mit einem "Dictionary" verbinden (vermutete Laufzeit: unter 10 Sekeunden)
maretz
maretz 26.11.2019 um 19:07:00 Uhr
Goto Top
das hängt jetzt davon ab was du genau machst und wo:
a) führst du deine Abfrage auf deinem Server aus oder auf nem Client? Wenn Client - das dürfte schon das erste Problem sein da du - je nach Client - eben wirklich Zeile für Zeile durchwanderst. Und jede Zeile wird artig aus der DB geholt, geändert, eingetragen, nächste zeile... DAS dauert eben - da die Leitungs-Geschwindigkeit egal ist, die Daten sind recht klein...

b) Machst du da ggf. String-Vergleiche? Auch diese dauern erheblich länger als nen reiner Vergleich auf Integer-Werte...

Da hilft ggf. einfach nur Warten...
Anna85
Anna85 28.11.2019 um 14:43:22 Uhr
Goto Top
Danke, aber die Datei ist zu groß, über 1 Mio Datensätze face-sad
Anna85
Anna85 28.11.2019 um 14:44:05 Uhr
Goto Top
Danke, wie gesagt, es funktioniert, aber es dauert über 1 Tag.
akretschmer
akretschmer 30.11.2019 um 14:17:44 Uhr
Goto Top
Mir ist nicht klar, was Du da machst, was Du erreichen willst und was daran so schwer ist.

Angenommen, ich habe diese Tabelle:


test=# create table tab2 (nummer int, prodnr uuid);
CREATE TABLE

Diese fülle ich mal, damit man überhaupt einige Sekunde Laufzeit messen kann, mit 2 Millionen Datensätzen:


test=# insert into tab2 select random()*700000, uuid_generate_v1() from generate_series(1,2000000);
INSERT 0 2000000


Eine Abfrage liefert nun:


test=*# select nummer, string_agg(prodnr::text,', ') from tab2 group by nummer limit 10; 
 nummer |                                                                                          string_agg                                                                                          
--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 430908 | a7493b53-1372-11ea-b00b-f832e4bf11a9, a840cef0-1372-11ea-b00b-f832e4bf11a9, a8fe8de1-1372-11ea-b00b-f832e4bf11a9, aa025f93-1372-11ea-b00b-f832e4bf11a9
 411809 | a70f73de-1372-11ea-b00b-f832e4bf11a9, a7978c6a-1372-11ea-b00b-f832e4bf11a9, a9c333f3-1372-11ea-b00b-f832e4bf11a9
   7004 | a6937aba-1372-11ea-b00b-f832e4bf11a9, a78e2217-1372-11ea-b00b-f832e4bf11a9, a7978e20-1372-11ea-b00b-f832e4bf11a9, a8dbd4a3-1372-11ea-b00b-f832e4bf11a9, a9eea24f-1372-11ea-b00b-f832e4bf11a9
 155703 | a862d589-1372-11ea-b00b-f832e4bf11a9, aa2d9285-1372-11ea-b00b-f832e4bf11a9, aa54bd78-1372-11ea-b00b-f832e4bf11a9
 297073 | a85d06b6-1372-11ea-b00b-f832e4bf11a9, a9e228df-1372-11ea-b00b-f832e4bf11a9
 194150 | a754e450-1372-11ea-b00b-f832e4bf11a9, a9e04623-1372-11ea-b00b-f832e4bf11a9
 549164 | a840d006-1372-11ea-b00b-f832e4bf11a9, aa505c5f-1372-11ea-b00b-f832e4bf11a9
 407952 | a7bdfd68-1372-11ea-b00b-f832e4bf11a9, a7f0e9fd-1372-11ea-b00b-f832e4bf11a9
 478578 | a809fcd2-1372-11ea-b00b-f832e4bf11a9, a815c1a0-1372-11ea-b00b-f832e4bf11a9, a8891fc5-1372-11ea-b00b-f832e4bf11a9, a9f3dc0d-1372-11ea-b00b-f832e4bf11a9, aa5da307-1372-11ea-b00b-f832e4bf11a9
    790 | a73e6d44-1372-11ea-b00b-f832e4bf11a9, a95a1c0e-1372-11ea-b00b-f832e4bf11a9
(10 rows)

Und die Laufzeit dafür ist:

test=*# explain analyse select nummer, string_agg(prodnr::text,', ') from tab2 group by nummer; 
                                                      QUERY PLAN                                                       
-----------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=56051.60..56054.10 rows=200 width=36) (actual time=2559.021..2823.612 rows=659393 loops=1)
   Group Key: nummer
   ->  Seq Scan on tab2  (cost=0.00..34395.30 rows=2165630 width=20) (actual time=0.015..298.032 rows=2000000 loops=1)
 Planning Time: 3.066 ms
 Execution Time: 2905.421 ms
(5 rows)

Also keine 3 Sekunden.


Deine tab1 kannst Du direkt entsorgen, da ja das Ergbniss der Abfrage offensichtlich das ist, was Du da haben willst.

Oder hab ich Dich komplett falsch verstanden?