mmofacts.com

Schnelle Querys

gepostet vor 16 Jahre, 10 Monate von _Jan_
Hi,
dieser Thred dient für alle zur Queryoptimierung. Zufällig (*hust*)
hab ich auch direkt eine Frage nach Optimierungsmöglichkeiten

SELECT
share_price
FROM
companies_stocks
WHERE
companies_stocks.date = (SELECT max(date)
FROM
companies_stocks cs2
WHERE
cs2.companie_id = companies_stocks.companie_id)
Die (Sub)Query scheint unheimlich langsam zu sein... gibt es Möglichkeiten sie zu verschnellern?
gepostet vor 16 Jahre, 10 Monate von Fobby
Auf jeden Fall per Datenbankstruktur, indem du companies_stocks.companie_id mit einem Index versiehst, falls nicht schon geschehen
Auf jeden Fall per Datenbankstruktur, indem du companies_stocks.companie_id mit einem Index versiehst, falls nicht schon geschehen
Schneller ist aber sicher auch

SELECT
share_price
FROM
companies_stocks
ORDER BY date DESC
LIMIT 0,1
gepostet vor 16 Jahre, 10 Monate von lauscher
bist du sicher, dass max wirklich langsamer ist als nen order befehl?
gepostet vor 16 Jahre, 10 Monate von Nuky
Kommt darauf an;
Auf jeden Fall beide Queries mal (einzeln) mit einem EXPLAIN ausführen. Was sagt Mysql dir dann?
gepostet vor 16 Jahre, 10 Monate von _Jan_
Fobbys Codevorschlag geht nicht, da ich nicht nur einen Maximaleintrag suche sondern einen pro Firmenid
gepostet vor 16 Jahre, 10 Monate von Drezil
Das kann ich dir so sagen .. also zumindest grob.
Da die Subquery dynamisch vom Feldinhalt abhängt, kann man diese nicht optimieren.
=> Sie muss auf jeder Zeile ausgeführt werden.
=> du hast de facto 1 + row_count Selects => lahm.
Das order hingegen:
selektiert erst alles (1 query) und muss das ergebnis aufbereiten. Geht auch fix, wenn nen Index drauf ist, aber liefert natürlich acuh doppelte.
Daher Fobbys Idee das mit nem limit zu machen. Nur hat seine Idee einen haken. es wird nur das aktuellste datum ausgegeben und nich das aktuellste pro company.
Daher was du suchst (mmn):
SELECT
share_price
FROM
companies_stocks
GROUP BY companie_id ORDER BY date DESC
einfach mal probieren
gepostet vor 16 Jahre, 10 Monate von _Jan_
Hey, danke Drezil. Das hat geklappt Ist ungefähr ~1000x schneller
gepostet vor 16 Jahre, 10 Monate von _Jan_
Doch nicht ganz

SELECT
max(date)
FROM
companies_stocks
GROUP BY companie_id
ORDER BY date DESC
bringt ein neueres Ergebnis als

SELECT
date
FROM
companies_stocks
GROUP BY companie_id
ORDER BY date DESC
Die erste Möglichkeit gibt ein aktuelleren Wert aus als die 2. Streiche ich beim 2. das Group by, bekomme ich auch dort auch die aktuellsten Werte :/ Ideen woran das liegen könnte?[es existiert zu jedem date jeweils ein Eintrag pro Firma]
gepostet vor 16 Jahre, 10 Monate von Lubi
Zuerst wird das Group-Statement ausgeführt (wenn ich mich so richtig entsinne) und dann erst das Order BY.

SELECT max(date) FROM companies_stocks
GROUP BY companie_id, date
ORDER BY date DESC
(ohne Gewähr, bin schon leicht müde...)
gepostet vor 16 Jahre, 10 Monate von knalli
Und wieder weg.. okay, also nur noch die/meine Lösung -_- Habe keinen Bock, alles nochmal zu tippen..
kurz: Das ist mE die Lösung, die du suchst.

SELECT
share_price, MAX(Date)
FROM
companies_stocks
GROUP BY
companie_id
HAVING MAX(date) = date
gepostet vor 16 Jahre, 10 Monate von _Jan_
@Lubi
Das würde funktionieren, gibt mir aber nicht den Wert von share_price wieder
@knalli
#1054 - Unknown column 'date' in 'having clause'
Die Spalte existiert aber
Ich werde wohl erstmal ein Workaround mit 2 Querys bauen
Su funktionierts

$d =
SELECT
max(date)
FROM
companies_stocks";

SELECT
companie_id, share_price
FROM
companies_stocks
WHERE date = $d
gepostet vor 16 Jahre, 10 Monate von Fornax
Original von _Jan_
#1054 - Unknown column 'date' in 'having clause'
Die Spalte existiert aber

Was, wenn du Tabellenname.date machst? Schon probiert?
gepostet vor 16 Jahre, 10 Monate von _Jan_
Ja geht auch nicht...
Habs jetzt mit 2 querys (siehe Post oben) dann gehts :/ Nicht schön aber funktional
gepostet vor 16 Jahre, 10 Monate von HSINC
wird wohl daran liegen das date nen reserviertes wort in mysql (bzw ansisql) ist und es deswegen unklug ist es als spaltennamen zu benutzen. deswegen zickt der wohl auch bei der having klausel rum
ansonsten, 2 querys statt einer sind nicht schlimm!! (solange man sie eben braucht).
gepostet vor 16 Jahre, 10 Monate von Lubi
der meckert bei Having immer dann, wenn nicht genau das Feld bereits im Abfrage-Ergebnis drin war (und MAX(date) date)
gepostet vor 16 Jahre, 10 Monate von Todi42
Ich glaube, die Group Implementierung von MySQL ist einfach etwas buggy ist. Eine group hat ja nur noch die Fehler, über die die Gruppe erstellt wurde, oder eben Funktionen (wie count(), max()), die auf alle Spalten aller Gruppenzeilen angewendet werden. Was sollte
SELECT date FROM companies_stocks GROUP BY companie_id
den für einen Wert für date liefern?
gepostet vor 16 Jahre, 10 Monate von Lubi
@Todi42:
SELECT date FROM companies_stocks GROUP BY companie_id
Liefert einen zufälligen Wert, bei dem companie_id zutrifft zurück (oder meckert, dass diese Kombination von Feld-Abfragen mit GROUP BY nicht gültig ist) - abhängig von der MySQL-Server-Version...
gepostet vor 16 Jahre, 10 Monate von knalli
Original von Lubi
der meckert bei Having immer dann, wenn nicht genau das Feld bereits im Abfrage-Ergebnis drin war (und MAX(date)
date)

Da das bei mir mit der Groups tabelle eines phpBB funktioniert hat, liegt es wohl an den reservierten Schlüsselwörtern; sollte sich umgehen lassen, indem du SELECT .. MAX(tabelle.date) as maxDate FROM as tabelle ... HAVING maxDate = tabelle.date verwendest.
Ich würde zwar auch nicht die Faustregel 1 > 2 Queries unterschreiben, aber man sollte dennoch nicht einfach 2 bauen..
gepostet vor 16 Jahre, 10 Monate von KoMtuR
reservierte schlüsselwörter in sql kann man doch entgehen, indem man ` nimmt.
Also müsste der Code so ausschauen:

SELECT
`share_price`, MAX(Date)
FROM
`companies_stocks`
GROUP BY
`companie_id`
HAVING MAX(`date`) = `date`
Zumindest hab ich das in meinen ersten Tagen SQL immer mit Hammer und Meißel eingetrichtert bekommen, dass man damit auf der sicheren Schiene ist
(PS.: Ich hab das erste date mal ohne gelassen, weil ich nicht wusste, ob das ne extra Bedeutung hat Schließlich ists groß und der Rest klein)
gepostet vor 16 Jahre, 10 Monate von knalli
... das im Übrigen groß geschrieben ist, mein Fehler.
gepostet vor 16 Jahre, 10 Monate von Kampfhoernchen
Groß-Kleinschreibung bei Tabellennamen und Funktionen ist in SQL schnuppe schnierz scheiß egal.
gepostet vor 16 Jahre, 10 Monate von Drezil
stimmt nicht.
In postgreSQL werden alle angabe als lowercase interpretiert. aber man kann eine spalte/tabelle auch explizit anders schreiben.
select * from "Foo" where Foo.bar = 1
liefert nen error, weil Foo nicht definiert ist. mit "Foo".bar gehts
Aber in dem betreffenden Beispiel war es in der tat egal, da das sowieso als lowercase intepretiert wird.

Auf diese Diskussion antworten