Autor |
Beitrag |
BrixxtoN
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 15:11
Hallo,
wenn ich eine abfrage "select * from kunden" mache, dauert es sehr lange ca. 1min bis das ergebniss angezeigt wird.
Weis jemand wie ich das beschleinigen kann.
Kundenanzahl: 26390
Datenbank: Firebird
Server: Firebird 2.5
Windows 7
Core i7
4 GB RAM
Delphi 2010
Komponenten: tSQLConnection, tSimpleDataSet (tSQLQuery genau so langsam), tDataSource, tDBGrid
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Mo 05.12.11 15:16
26.000 ist ja nun auch nicht gerade wenig. Und so viele Kunden in einer Liste - da findet kein User das, was er sucht. Filtere die Datensätze raus, die der User wirklich benötigt.
Du solltest aber SELECT * immer vermeiden. Beschränke das auf die Felder, die Du wirklich brauchst.
Große Blob-Felder in der Tabelle? Bei Blobs mit vielen Daten ist es evtl. sinnvoll, sie in eine 1:1-Tabelle auszulagern.
Datenbank liegt lokal? Oder Netzwerk? Wie sieht der Server aus? Hatte mal einen Kunden, der sich über eine langsame Software beschwerte. Auf die Frage, wie viel Ram hat der Server denn sagte er "1 GB" (bei einem Windows 2003-Server). Auf 4 GB aufgerüstet - zack, Datenbank 3x schneller.
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 15:28
Ich finde das 26000 Datensätze nicht viel sind.
Wenn ich die selbe abfrage mit dBase-Datenbank und ADS-Komponenten mache geht das in 2-3 Sekunden.
Komponenten: ADSConnection, ADSQuery, DataSource, DBGrid
Datenbank ist Momentan auf meinem Notebook (Lokal) mit Windows 7, Core i7 und 4 GB RAM.
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Mo 05.12.11 16:38
26000 dürfte auch gar kein Problem sein (selbst mit Select * unter 2 sec).
Ich lese in manchen Modulen zw. 200.000 und 300.000 DS aus der DB, schaufel die in ein ClientDataSet und das ganze in unter 10 sec. inkl. Anzeige in Maske.
Haste Indexe auf der Tabelle ?
Das spielt definitiv ne große Rolle bei der Geschwindigkeit.
Indiziertes Lesen ist gegenüber sequentiellem Lesen um ein vielfaches schneller.
Wenn es langsam ist, liegt es eben auch oft am Netzwerk (falls das ne Rolle bei dir spielt) oder ne Firewall/Antivirus kann auch mal für einiges an Zeitverlust sorgen.
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mo 05.12.11 16:39
Wie lautet die Endung der Datenbank?
_________________ Markus Kinzler.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 17:14
Datenbankendung ist FDB.
Ja ich habe 3 Indexe.
1. Index = Spalte ID als Unique Index
2. Index = Spalte Kundennr
3. Index = Spalten STANDORT, GELOESCHT, NOEXPORT
Ich hoffe die Indexe sind richtig aufgebaut.
1. Test
ADS-Komponenten und dBase Datenbank = 2-3 Sekunden
2. Test
ADO-Komponente und ODBC für Firebird = 2-3 Sekunden
3. Test
dbExpress und Firebird = 1 Minute
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mo 05.12.11 17:16
Wie sieht die Abfrage aus?
_________________ Markus Kinzler.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 17:25
Bei den Tests habe ich
SQL-Anweisung
verwendet.
In meiner Software ist die abfrage
SQL-Anweisung 1:
| select * from kunden where (geloescht!=1 or geloescht is null) |
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mo 05.12.11 17:30
Dann hilft ja keiner der Indizes. Das Problem scheint aber eher an dbExpress zu liegen, sonst wäre die Abfrage per ODBC ja auch nicht schneller
_________________ Markus Kinzler.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 17:40
Wie müsste ich die Indezes aufbauen das es besser wird?
Das hab ich mir auch gedacht das es an dbExpress liegen müsste.
Es gibt doch auch andere Entwickler die dbExpress nutzen mit mehr als 26000 Datensätzen, es wundert mich das bei anderen funktioniert.
Ich habe es auch auf verschidenen Rechnern getestet, weil ich dachte es liegt an der Entwicklungsumgebung auf meinem Notebook.
Es ist auf allen Rechnern das gleiche Problem.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mo 05.12.11 17:42
Die Indizes helfen ja nur, wenn du diese auch in der Abfrage brauchst.
Wenn du oft where geloescht = :Wert benutzt, dann macht ein Index auf die Spalte "geloescht" Sinn.
Wenn du jedoch einfach select * from kunden ohne WHERE-Bedingung ausführst, sind die Indizes egal.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 17:48
Dann ist der 3. Index für meine Abfrage schon richtig.
3. Index = Spalten STANDORT, GELOESCHT, NOEXPORT
SQL-Anweisung 1:
| select * from kunden where (geloescht!=1 or geloescht is null) |
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mo 05.12.11 18:07
Nein, weil du GELOESCHT in der Where-Clause abfegragt wird.
_________________ Markus Kinzler.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Mo 05.12.11 19:00
3. Index = Spalten STANDORT, GELOESCHT, NOEXPORT
SQL-Anweisung 1:
| select * from kunden where (geloescht!=:wert or geloescht=:wert2) |
Params:
wert=1
wert2=Null
Ist das jetzt richtig, macht jetzt 3. Index sinn.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 06.12.11 00:06
Dein 3. Index ist eine Kombination. Wenn du nur eines dieser Kombi-Felder in der Where-Klausel hast, nützt das nichts. Außerdem fragst auf ungleich ab. Das kann auch dazu führen, dass ein Index nicht gezogen wird.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 06.12.11 10:20
Du solltest auch nicht geloescht=:wert nutzen wenn wert=null. Nimm statt dessen lieber geloescht is null.
Performanter wäre es jedoch die Spalte geloescht auf not null mit einem Default-Wert (0) zu versehen.
Dann kannst du dir die Abfrage auf null sparen und die DB kann den Index performanter gestalten, da der null-Fall nicht extra behandelt werden muss.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Di 06.12.11 12:22
Neuer Test:
4. Index = Spalte GELOESCHT
SQL-Anweisung 1:
| select * from kunden where geloescht=:wert |
Params:
wert=0
Genau so langsam.
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Di 06.12.11 12:52
Ich habe festgestellt, wenn ich das Notizfeld (BLOB SUB_TYPE TEXT) aus der Datenbank lösche, hab ich die Probleme nicht mehr.
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Di 06.12.11 12:54
Tja, wie ich bereits in meiner ersten Antwort sagte: Blobfelder machen gern Probleme. Lager sie in eine 1:1-Tabelle aus.
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
BrixxtoN 
      
Beiträge: 50
Win 7 64bit
Delphi 2010 Enterprise
|
Verfasst: Di 06.12.11 13:02
Ich brauche das Feld zur anzeige und wenn ich es auslager muss ich trotzdem noch einer SQL-Abfrage auf das Feld machen.
Ist das dan schneller?
Was ich noch immer nicht verstehe, warum funktioniert das mit ADO und ADS.
|
|