PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL Performance (Query failed)


mapel110
2008-05-14, 11:23:55
SELECT max(uhrzeit) FROM bbbb

Bei 2 Mio Datensätzen läuft das auch noch. Bei 11 Mio Datensätzen dann nicht mehr. Warum?!

Ich bekomme kein PHP-Timeout und im SQL-Management-Studio tuts diese Abfrage auch. Aber in meinem Script kommt "Query failed".

/edit
jetzt hab ich von den 11 Mio Einträgen 8 Mio gelöscht und jetzt läufts wieder. Aber das kann doch nicht im Sinne des Erfinders sein...

Coda
2008-05-14, 15:38:11
Schau dir halt die Fehlermeldung an die dein SQL-Server zurückgibt. Da gibt's sicher ne Möglichkeit.

Gast
2008-05-14, 15:48:13
Den Timeout musst du garantiert bei deinem PHP Script in den jeweiligen Datenzugriffszeugs definieren.

mapel110
2008-05-14, 16:19:48
Ich bekomme ja kein PHP-timeout. Oder gibts bei PHP noch was anderes zusätzliches zu ini_set('max_execution_time','120');?

Warning: mssql_query() [function.mssql-query]: Query failed in D:\www-daten\035\PraktApel\index.php on line 238
Mehr steht im Browser nicht. Es folgt natürlich noch die Fehlermeldung von fetch_row usw., aber das wars.
Oder liefert SQL noch mehr an den Browser zurück, das man auswerten kann?

Jedenfalls, wie schon geschrieben, selbe Abfrage im SQL-Management Studio bringt das gewünschte Ergebnis. Da gibts keinen Fehler.

Coda
2008-05-14, 16:26:57
php.ini mssql.timeout

Allerdings habe ich keine Ahnung wie du es schaffst dafür 60 Sekunden zu verbraten. Mach nen Index auf die Uhrzeit, dann sollte das in <1s gehen.

mapel110
2008-05-14, 16:35:35
Ah okay, Danke.

Dann werd ich morgen mal fragen, ob das möglich ist bei den Daten. Das sind Echtzeitdaten vom Callmanager und ob die da dann auch regelmäßig indizieren, damit mein kleines, blödes Statistik-Script funktioniert, ist leider fraglich. ;(

Berni
2008-05-14, 16:58:51
Vergebt ihr fortlaufende IDs in der Tabelle als Primärschlüssel? Dann könntest du möglicherweise auch genauso hier einfach das Maximum nehmen. Ansonsten ist das Erstellen so eines Indexes ja kein großes Ding und bei großen Datenbanken unumgänglich (wird aber beim ersten Mal recht lange dauern weil er ja erstmal alle 11 Mio. durchgehen muss). Evtl. wäre auch zu überprüfen, ob diese Uhrzeit nicht beim Eintragen schon ausgewertet werden kann (entweder im Programm oder über einen Trigger) und dann das Maximum woanders (Textdatei oder andere Tabelle) gespeichert wird.

Coda
2008-05-14, 19:21:42
Ah okay, Danke.

Dann werd ich morgen mal fragen, ob das möglich ist bei den Daten. Das sind Echtzeitdaten vom Callmanager und ob die da dann auch regelmäßig indizieren, damit mein kleines, blödes Statistik-Script funktioniert, ist leider fraglich. ;(
*bags head against table*

http://de.wikipedia.org/wiki/B-Tree

mapel110
2008-05-14, 21:29:06
Für mich n00b bitte in Deutsch.
Binärbäume kenne ich noch ausm Studium. Bezug zu dem Problem hier? :confused:

Gast
2008-05-14, 21:30:57
B-Baum steht nicht für Binärbaum. Ein Knoten in einem Binärbaum besitzt höchstens zwei Verweise auf Kindknoten, während in einem B-Baum ein Knoten eine Vielzahl von Verweisen auf Kindknoten speichern kann

mapel110
2008-05-14, 21:33:30
B-Baum steht nicht für Binärbaum. Ein Knoten in einem Binärbaum besitzt höchstens zwei Verweise auf Kindknoten, während in einem B-Baum ein Knoten eine Vielzahl von Verweisen auf Kindknoten speichern kann
Interessant, dass es da mehrere Abkürzungen gibt. Okay. Aber was will mir Coda damit sagen? (außer dass ich keine Ahnung habe natürlich *scnr*)

AtTheDriveIn
2008-05-14, 21:50:01
Erstellst du einen Index auf die Uhrzeit, dann wird im Hintergrund ein B-Baum aufgebaut, dieser ist immer ausbalanciert und ermöglicht so eine schnelle Suche. Es kann also so gar nicht sein das ein Timeout erfolgt.

create index uhr_index on bbbb(uhrzeit)

Berni
2008-05-14, 23:12:13
Es kann also so gar nicht sein das ein Timeout erfolgt.
Och bei genügend großer Datenmenge kanns auch mit B-Tree-Index irgendwann mal lahm werden ;) Nur wird das in nem normalen Anwendungsfall eben nicht auftreten, da hast du recht.

mapel110
2008-05-14, 23:19:18
create index uhr_index on bbbb(uhrzeit)
So einfach ist das?! :O
Aber das muss dann ja regelmäßig gemacht werden, also der Zuwachs muss mit einem Index versehen werden.
Da liegt dann wohl das Problem. Ich muss das dann morgen abklären. Aber danke soweit.

ach IDEE! Ich kann das ja in mein Programm einbauen und das eben ausführen, falls ein Monat/Tag vergangen ist. Allerdings braucht derjenige dazu mehr als Leserechte für die Datenbank. :uponder:

AtTheDriveIn
2008-05-14, 23:29:22
So einfach ist das?! :O
Aber das muss dann ja regelmäßig gemacht werden, also der Zuwachs muss mit einem Index versehen werden.
Da liegt dann wohl das Problem. Ich muss das dann morgen abklären. Aber danke soweit.

ach IDEE! Ich kann das ja in mein Programm einbauen und das eben ausführen, falls ein Monat/Tag vergangen ist. Allerdings braucht derjenige dazu mehr als Leserechte für die Datenbank. :uponder:

Wenn du auf eine Tabellenspalte einen Index erstellst, dann wird der B-Baum bei jedem Insert in diese Tabelle automatisch ausbalanciert.

Mit dem Create Index Befehl erstellst du einen Index, der dann dann zur Datenbank gehört. Für das Erstellen müsstest du natürlich mit entsprechenden Rechten ausgestattet sein...

AtTheDriveIn
2008-05-14, 23:55:38
Och bei genügend großer Datenmenge kanns auch mit B-Tree-Index irgendwann mal lahm werden ;) Nur wird das in nem normalen Anwendungsfall eben nicht auftreten, da hast du recht.


Theoretisch ja, praktisch wird die Suche nicht wirklich langsam werden, da bei entsprechender Wahl der Knotengröße sehr wenige Festplattenzugriffe für enorme Datenmengen notwendig sind.

Coda
2008-05-15, 00:20:17
So einfach ist das?! :O
Aber das muss dann ja regelmäßig gemacht werden, also der Zuwachs muss mit einem Index versehen werden.
Da liegt dann wohl das Problem. Ich muss das dann morgen abklären. Aber danke soweit.

ach IDEE! Ich kann das ja in mein Programm einbauen und das eben ausführen, falls ein Monat/Tag vergangen ist. Allerdings braucht derjenige dazu mehr als Leserechte für die Datenbank. :uponder:
mapel. Erstell einfach einen Index auf die Spalte und freu dich auf etwa Faktor 1.000.000x schnelleren Zugriff darauf ohne irgendwas anderes machen zu müssen. Der Index wird bei jedem Löschen oder Einfüge für dich vom DB-Server automatisch mit verändert. Ansonsten hätte eine Datenbank absolut keinen Sinn und du könntest auch gleich ne Textdatei nehmen um 11 Mio. Zeilen zu speichern. Das wäre dann ungefähr gleich schnell als das was du hier machst.

Okay?

Gast
2008-05-15, 08:56:44
Theoretisch ja, praktisch wird die Suche nicht wirklich langsam werden, da bei entsprechender Wahl der Knotengröße sehr wenige Festplattenzugriffe für enorme Datenmengen notwendig sind.

Dafür wird die Verwaltung des B-Baum selbst mit der Zeit aufwendig. Kommt eben drauf an in welchem Zeitraum dann Inserts/Updates passieren. Außerdem neigt ein B-Baum dazu zu fragmentieren.

Gast
2008-05-15, 08:59:01
^^ Habe mich verschrieben: Es kommt natürlich drauf an, wann Inserts/Selects passieren.

mapel110
2008-05-15, 09:20:36
create index uhr_index on bbbb(uhrzeit)
Okay, das hab ich ausgeführt und das hat etwa 2 Minuten gedauert bei den 11 Mio Einträgen.

Aber an der Performance meines Scripts hat das leider nichts geändert. Muss ich die Abfragen dann noch irgendwie anpassen?

freu dich auf etwa Faktor 1.000.000x schnelleren Zugriff darauf ohne irgendwas anderes machen zu müssen.
.... Hört sich nicht so an. Also hab ich noch irgendeinen anderen Fehler eingebaut, der massiv Performance kostet?! :uponder:

/edit
ah, der Index ist noch nicht richtig konfiguriert. Ich hab da jetzt erstmal auf "Gruppiert" umgestellt. Das dauert ...
/edit2
Funzt jetzt alles bestens und sehr fix. Danke. :]

mapel110
2008-05-15, 14:39:51
Eine Frage dazu hab ich allerdings doch noch.

Ich will auch auf der Startpage die Anzahl der Datensätze angeben. Wenn ich nun aber COUNT(*) benutze, braucht er seine Minute dafür. Kann ich nun irgendwas schnelleres benutzen? Im Netz fand ich jedenfalls immer nur die Lösung mit COUNT.

AtTheDriveIn
2008-05-15, 15:51:35
was mir auf die Schnelle eingefallen ist:
Du könntest einen Trigger erstellen der bei Insert und Delete in der Tabelle bbbb aufgerufen wird und einen Datensatz in einer weiteren Tabelle mit Statistikwerten verändert.

Du müsstest dann für die Anzahl der Datensätze nur die richtige Spalte in der Statistiktabelle auslesen.

mapel110
2008-05-15, 16:08:00
was mir auf die Schnelle eingefallen ist:
Du könntest einen Trigger erstellen der bei Insert und Delete in der Tabelle bbbb aufgerufen wird und einen Datensatz in einer weiteren Tabelle mit Statistikwerten verändert.

Du müsstest dann für die Anzahl der Datensätze nur die richtige Spalte in der Statistiktabelle auslesen.
Auch eine gute Idee.



Ich muss leider erstmal darauf hoffen, dass der Datenbestand überhaupt indiziert wird. Der gute Mann da unten meinte nämlich "Oh, so viele Indizes. Brauchen sie die überhaupt alle? Das belastet ja den Server stärker. Das muss ich erst testen." :ugly:

Ansonsten hätt ich nämlich gedacht, dass man vielleicht den Index selbst auslesen kann und dort eben den MAX zurückgeliefert bekommt. Aber google ist bei dem Begriff "index" generell etwas ..naja.. komisch. index.htm usw halt...

Coda
2008-05-15, 16:56:32
Eine Frage dazu hab ich allerdings doch noch.

Ich will auch auf der Startpage die Anzahl der Datensätze angeben. Wenn ich nun aber COUNT(*) benutze, braucht er seine Minute dafür. Kann ich nun irgendwas schnelleres benutzen? Im Netz fand ich jedenfalls immer nur die Lösung mit COUNT.
Das ist seltsam. Count sollte eigentlich in O(1) laufen.

Ich muss leider erstmal darauf hoffen, dass der Datenbestand überhaupt indiziert wird. Der gute Mann da unten meinte nämlich "Oh, so viele Indizes. Brauchen sie die überhaupt alle? Das belastet ja den Server stärker. Das muss ich erst testen." :ugly:
Der hat ja selber keinen Plan! Omg.

Berni
2008-05-16, 03:09:39
Ansonsten hätt ich nämlich gedacht, dass man vielleicht den Index selbst auslesen kann und dort eben den MAX zurückgeliefert bekommt. Aber google ist bei dem Begriff "index" generell etwas ..naja.. komisch. index.htm usw halt...
Also wenn ein Index erstellt ist, wird er automatisch verwendet wenn er (für das Datenbanksystem) sinnvoll erscheint.
Wenn du nach "index" suchst, ists ja klar dass nur müll kommt. Musst halt noch ein "SQL" oder "MSSQL" dazusetzen...

Ich will auch auf der Startpage die Anzahl der Datensätze angeben. Wenn ich nun aber COUNT(*) benutze, braucht er seine Minute dafür.
Du könntest versuchen, statt dem Count(*) ein Count(Spalte_mit_Index) zu machen (wobei Spalte_mit_Index natürlich entsprechend zu ersetzen ist ;)). Zumindest bei MySQL hilft das manchmal, keine Ahnung wie das bei MSSQL ist.

Ich muss leider erstmal darauf hoffen, dass der Datenbestand überhaupt indiziert wird. Der gute Mann da unten meinte nämlich "Oh, so viele Indizes. Brauchen sie die überhaupt alle? Das belastet ja den Server stärker. Das muss ich erst testen."
Der gute Mann hat auch recht. Je mehr Indizes, desto langsamer werden Einfügeoperationen, weil ja immer der Index upgedated werden muss. Besonders gruppierte Indexe können problematisch werden, weil dann unter Umständen bestehende Datensätze verschoben werden müssen.

Generell muss ich mal folgendes loswerden (ist nicht böse gemeint): Du hast scheinbar recht wenig Ahnung von dem was du hier machst - ist das schon der richtige Job für dich? Man kann sehr viel optimieren und ändern aber wenn man sich nicht auskennt kann man auch ne Menge kaputt machen. Das Forum hier kann da auch nur teilweise drüber hinweg helfen weil wir ja nicht mal genau wissen, wie die Tabellen aussehen, welche Last besteht, welche Hardware verwendet wird und was überhaupt genau rauskommen soll. Offensichtlich liest du auch nicht mal richtig, denn die Idee mit dem Trigger hatte ich schon auf der ersten Seite geäußert :rolleyes:

mapel110
2008-05-16, 06:52:23
Mein Problem ist, dass ich zu viel lese. Und da überlese ich auch einiges. Sry dafür.

Ich hab wenig Ahnung. Natürlich. Ich bin ja auch ein Azubi und mache derzeit ein Praktikum im Rahmen einer schulischen Ausbildung. Das allergrößte Problem dabei ist, dass ich hier am Praktikumsplatz keinen Ansprechpartner habe, der gut programmieren kann. Ich muss mir hier alles zusammensuchen und basteln. Das braucht Zeit. Wirklich programmieren lerne ich wohl erst bei meinem ersten Arbeitgeber nach der Ausbildung. Hier im Berufsförderungswerk wird mir das nicht möglich sein.

Lösungsvorschläge werd ich gleich an der Arbeit ausprobieren, danke an alle.

/edit
Also mit dem Zählen einer der indizierten Spalten komme ich auch nicht weiter. Das dauert auch. Es liegt wohl daran, dass nicht alle Spalten der gesamten Tabelle indiziert sind, sondern eben nur 5 (die, die ich eben für mein Script brauche).


Wenn du nach "index" suchst, ists ja klar dass nur müll kommt. Musst halt noch ein "SQL" oder "MSSQL" dazusetzen...

http://www.google.com/search?hl=de&client=opera&rls=en&q=sql+index+auslesen&btnG=Suche&lr=
Halt Müll, was dabei rauskommt...

Berni
2008-05-16, 12:34:15
Also ich hab mal nach "MSSQL count index" gesucht und da findet man schon brauchbares.
Für das Count() kann MSSQL soweit ich das gelesen habe nur nonclustered (also nicht-gruppierte) Indexe verweden. Ich habe da noch folgende Lösung gefunden: http://www.mssqlcity.com/Articles/KnowHow/RowCount.htm
SELECT rows FROM sysindexes WHERE id = OBJECT_ID('tabellenname') AND indid < 2

Allerdings kann dieses Ergebnis minimal abweichend sein von einem Count(*) weil dieses Statistik nicht dauernd upgedated wird und und heftiger Last somit um Einiges hinterherhinken kann. Mit Adminrechten kann man das aber manuell updaten: http://www.sqlhacks.com/index.php/Administration/Row-Count-Inaccurate

AtTheDriveIn
2008-05-16, 13:18:03
Ich hab wenig Ahnung. Natürlich. Ich bin ja auch ein Azubi und mache derzeit ein Praktikum im Rahmen einer schulischen Ausbildung...

nach dem Studium nochmal eine schulische Ausbildung? Oder hast du abgebrochen?



@Thread: Count(primärkey_der_Tabelle) würde ich auch mal versuchen, afaik besteht auf dem prim-key eh ein Defaultindex.

mapel110
2008-05-20, 18:24:17
Sry, ich hatte das Thema hier ganz übersehen. Derzeit hab ich andere Probleme mit dem Programm, die ich aber denke ich allein lösen kann. Dieses hier im Thread hat jedenfalls geringe Priorität, aber wenn ich am Ende noch Zeit haben sollte... in 3 Wochen muss ich fertig sein, eigentlich in 2 Wochen :ugly:

Studium abgebrochen ja, und ich traue es mir derzeit auf jedenfall nicht zu, es fortzusetzen. Deshalb erstmal Ausbildung und dann weitersehen.