SQL Auswertung Tabellen

Diskutiere SQL Auswertung Tabellen im Developer Network Forum im Bereich Hardware & Software Forum; Guten Tag zusammen, habe mal wieder ein Problem mit dem SQL Zeugs. Auf einer WebSite wird für User die Hits gespeichert. Pro klick ein...
  • SQL Auswertung Tabellen Beitrag #1
B

Bitz683

Mitglied
Dabei seit
30.06.2006
Beiträge
10
Reaktionspunkte
0
Guten Tag zusammen,

habe mal wieder ein Problem mit dem SQL Zeugs. Auf einer WebSite wird für User
die Hits gespeichert. Pro klick ein Datensatz in der Tabelle Hits. Es soll nun für
die Administratoren die Möglichkeit geben eine Statistik eines frei wählbaren Zeit
raums auszugeben.
Das Problem dabei ist nun, das die Abfrage solange dauert, dass der SQL-Server
nachdem Timeout stribt.

Die Tabelle hat die Felder
Id int PK
org char(5)
lan char(5)
NavigationId int
Name varchar(255)
inputdate datetmie
Jahr int
Monat int
Tag int
Datum int

Ich hatte zuerst das Datum anhand des Feldes InputDate eingeschränkt. Dazu
musste ich es erst convertieren um die Zeit abzuschneiden und habe es an-
schliesen wieder zu Datetime convertiert. selbes auch mit dem übergebenen
Datum (jedoch ohne vorher die zeitabzuscheiden)

convert(datetime, convert(varchar(10), InputDate), 104)
=, >=, <=, <, >
convert(datetime, DatumVon )

Sowie entsprechnd mit DatumBis. Erg dabei: Timeout selbst bei einer Differenz
von einer Woche.
Drum die Felder Jahr, Monat und Tag. Hierbei kann ich bereit einen Zeitraum
von einem Monat auswählen und die Abfrage bracuht nur ca. 15 sec.
Problem evtl. dabei Ich habe bei einem großen Zeitraum in der Where-Klausel
relativ viele Einschränkungen.
(
(Jahr = 2007 and Monat = 5 and Tag > 15)
or
(Jahr = 2007 and Monat > 5)
or
(Jahr = 2008)
)
Wenn wir nun das Jahr 2010 haben kommen eben für 2009 und 2010 weitere
Einschränkungen dazu. Noch mehr sind es wenn ich das Bis Datum noch ein-
schränke.

Drum meinte ich, dass die Lösung über das Feld Datum kommt. Jedoch habe
dabei sogar das Problem, dass das Statement noch langsamer ist. Was ich
nicht verstehe :confused:

Bei meinen Tests habe ich dabei unterschiedliche Indexe auf die Tabelle gelegt
einmal auf Org und Lan sowie auf Jahr, Monat und Tag.
dann einen auf Org und Lan sowie Datum
einen auf Org und Lan sowie auf InputDate.
Schnellste Ergebnis brachte mir die Abfrage über Jahr, Monat und Tag und
einem Index auf die Felder Org, Lan, Jahr, Monat, Tag ( also ein index und
nicht zwei) Zeitraum zum test war ein Monat. Result kam nach ca. 15. sec

Achso und von der Datenmenge her. Es kommen kommen ca. 300000 Daten-
sätze pro Monat dazu. Derzeit sind ca. 4,5 Mio enthalten.

Nun zu meinem eigentlichen Anliegen: wie muss ich die Tabelle aufbauen, um
diese möglichst schnell abfragen zu können. Habe ich die Indexe falsch er-
stellt.

Ich hoffe ich habe mein Problem so beschrieben das mans auch versteht und
hoffe auf Hilfreiche Antworten

Vielen Dank mal
Gruß Bitz
 
  • SQL Auswertung Tabellen Beitrag #2
O

O Love

Bekanntes Mitglied
Dabei seit
08.04.1999
Beiträge
2.286
Reaktionspunkte
0
Datumsintervalle prüft man besser in der Form:
Code:
Datum between @Von and @Bis
Bei diesem Ausdruck sind die Intervallgrenzen mit enthalten. Falls der letzte Tag des Intervalls eine Uhrzeit hat, dann übergib an @Bis halt Enddatum + 1.

Um aber Dein Problem mittels Index auf Datum zu beschleunigen, mußt Du schon beim Einfügen der Daten Datum und Uhrzeit trennen. Schreib Dir dazu am besten gleich SQL-Funktionen, die das erledigen, also quasi Fct_Date_DatePart und Fct_Date_TimePart zur Benutzung in Bulk Inserts. Da Du ja meiner Meinung nach MS-SQL benutzt, geht das ab MS-SQL 7.

Den Datumsanteil bekommst Du auch ohne String-Konvertierungen, die sicher auch noch um einiges langsamer sind:
Code:
cast (floor (cast (Datum as float)) as datetime)
Beim Zeitanteil ziehst Du die Ganzzahl halt ab.
 
  • SQL Auswertung Tabellen Beitrag #3
B

Bitz683

Mitglied
Dabei seit
30.06.2006
Beiträge
10
Reaktionspunkte
0
Schönen Guten Morgen O Love und rest,

[...]Da Du ja meiner Meinung nach MS-SQL benutzt,
geht das ab MS-SQL 7.[...]
Hatte ich total vergessen mit zu schreiben um welche Art von SQL Server es
sich handelt. Aber ja du liegst richtig. MS SQL Server 2000 bzw. 2005. beide im Einsatz.

Nun aber zu deinen Vorschlägen:

Datumsintervalle prüft man besser in der Form:
Code:

Datum between @Von and @Bis

Bei diesem Ausdruck sind die Intervallgrenzen mit enthalten. Falls der letzte Tag des Intervalls eine Uhrzeit hat, dann übergib an @Bis halt Enddatum + 1.

Um aber Dein Problem mittels Index auf Datum zu beschleunigen, mußt Du schon beim Einfügen der Daten Datum und Uhrzeit trennen. Schreib Dir dazu am besten gleich SQL-Funktionen[...]

Ich habe mich vielleicht etwas unverständlich ausgedrückt. Also wenn ein Hit
in die Tabelle gespeichert wird, speichere ich IMMER in das Feld InputDate
das aktuelle Datum (per getdate()). Bislang habe ich auch dieses Feld abge-
fragt in der Form

convert(datetime, convert(varchar(10), InputDate, 104)) >= DatumVon
and
convert(datetime, convert(varchar(10), InputDate, 104)) <= DatumBis

Das ist wahrlich schlecht, da die Konfertierung extrem langsam ist. Ich hatte
als ich die Tabelle entwarf bereits drei zusätzliche Felder erstellt. Tag, Monat
und Jahr. Hier speichere ich gleichzeitig den Tag (day(getdate()), den Monat
(month(getdate()) sowie das Jahr (year(getdate()). D. H. eine Trennung der
Daten existiert bereits.
Nachdem ich das Problem der Geschwindigkeit bekam, habe ich es zuerst ver-
sucht mit between zu lösen. Jedoch konnte das Skript auch hier nicht mehr
beendet werden. Ich habe dann die drei Felder (Tag, Monat, Jahr) genommen
und frage nun diese ab, was deutlich schneller ist als das mit between (ich
habe auch hier kein convert mehr geamcht sondern so wie in deinem Vor-
schlag beschrieben). Aber nur wenn die Indexe auf diese Felder gelegt sind.
Wie bereits beschrieben habe erst dann ein neues Feld erstellt, welches das
Datum im Format JJJJMMTT also für heute zum Beispiel '20080407' in die
Spalte schreibt. Dieses Feld dann auch per Between abgefragt und auch ver-
sucht es über die Operatoren >, <, <=, >= einzuschränken aber auch diese
Art ist Langsamer als eine Abfrage auf die Felder Tag, Monat und Jahr.

Ich habe die Tabelle dabei immer für den Zeitraum vom 01.06.2007 bis zum
30.06.2007 eingegrenzt (Keine weiteren Tabellen wurde dabei mit abgefragt)

Select count(Id) from Hits
where

inputdate between '01.06.2007' and '30.06.2007'

Dauer: ca. 46 sec
--------------------------------
Select count(Id) from Hits
where

datum between '20070601' and '20070630'

Dauer: ca. 34
--------------------------------
Select count(Id) from Hits
where
Jahr = 2007 and Monat = 6

Dauer:ca. 21

wie geschrieben sind davon ca. 300000 Datensätze betroffen. Ich habe pro
Abfrage den Index immer entsprechend der Felder erstellt.

Wenn es weniger Datensätze wären aber leider ist es nicht so. Die Abfrage ist
bei eine Zeitraum von einem Monat bereits derart langsam und es sollten auch
Abfrage über mehrere Monate funktionieren. Es muss doch eine Lösung geben.

Sollte man es evtl. komplett anderst speichern.

Grüße Bitz
 
  • SQL Auswertung Tabellen Beitrag #4
O

O Love

Bekanntes Mitglied
Dabei seit
08.04.1999
Beiträge
2.286
Reaktionspunkte
0
Wie gesagt, ich würde 2 Spalten für den Zeitpunkt anlegen, eine Datum- und eine Zeit-Spalte, Datentyp aber jeweils datetime (und bloß nicht char!). In diese bitte nur die aufgespaltenen Anteile beim Befüllen eintragen. Damit wird zwar das Eintragen langsamer, aber Auswertungen schneller. Auf die Datum-Spalte legst Du einen Index.

Im Enterprise Manager gibt es auch einen Index-Optimierer, den kannst Du gerne mal laufen lassen. Vielleicht schlägt er Dir für Deine komplette Tabelle einen besseren, kombinierten Index vor.

Wenn es Dir am Ende nur um komplette Tage bzw. Monate geht, kannst Du für Auswertungen die Daten konsolidieren und am Tages- bzw. Monatsende via SQL-Job eine Zusammenfassung in eine extra Tabelle schreiben. Wer genauere Daten will, muß in die "große" Tabelle rein, kann dort aber nur über einem kürzeren Intervall arbeiten.
 
  • SQL Auswertung Tabellen Beitrag #5
B

Bitz683

Mitglied
Dabei seit
30.06.2006
Beiträge
10
Reaktionspunkte
0
Guten Tag,

das ist mal eine Hilfreiche Idee. Super, Danke. Das ich nicht selbst
drauf gekommen bin. Werde einfach eine neue Tabelle erstellen
und per SQL-Job jeden Tag einen neuen Datensatz mit der Summer
der Hits füllen. So habe ich ja pro Jahr max. 365 Datensätze. Muss
ja schneller gehen :victory:

Nochmals Danke

Gruß Bitz
 
  • SQL Auswertung Tabellen Beitrag #6
cmddegi

cmddegi

Bekanntes Mitglied
Dabei seit
12.07.2001
Beiträge
4.740
Reaktionspunkte
0
Ort
Austria
Dann weißt du aber nicht mehr im Detail, wer wann die Seite aufgerufen hat, sondern nur, wie viele pro Tag. Außer natürlich, du verwendest das nur als schnelle Übersicht. Kommt einfach drauf an, was du genau machen möchtest, bzw. wie detailliert die Daten sein sollen.
 
Thema:

SQL Auswertung Tabellen

ANGEBOTE & SPONSOREN

https://www.mofapower.de/

Statistik des Forums

Themen
213.179
Beiträge
1.579.172
Mitglieder
55.878
Neuestes Mitglied
Satan666
Oben