mmofacts.com

Mein Monster-Query ;)

gepostet vor 16 Jahre, 10 Monate von RaydenDD
So hier darf jeder seine supertollen SQL Query's reinstellen, umso monströser umso besser. Ich fange an
PS: Beim joinen von temporären Zwischentabellen .. gibt es hier spezielle Optimierungsmethoden?

SELECT * FROM (SELECT tp.id as tradepostId, tof.id as offerId, tp.planetId, tof.userId, tof.resstype, tof.quantity, tof.offerType FROM tradepost tp, tradeoffer tof WHERE tp.userId
706 AND tof.userId=tp.userId) as basicInfo
LEFT OUTER JOIN
(SELECT freeShips.tradepostid, SUM(freeShips.count * sd.ressSpace) as capacity, MAX(sd.hyperspeed) as speed
FROM ( SELECT tps.tradepostid, tps.designId, (tps.count - tf.count) as count
FROM tradepostship tps
LEFT OUTER JOIN
( SELECT tradepostId, designId, SUM(count) as count
FROM tradefleets tf GROUP BY tradepostId, designId) as tf
ON tf.tradepostId=tps.tradepostid AND tf.designId=tps.designId WHERE tps.tradepostid=106) as freeShips
LEFT OUTER JOIN shipdesigns sd ON sd.id=freeShips.designId GROUP BY freeShips.tradepostid) as info
ON info.tradepostid=basicInfo.tradepostId
gepostet vor 16 Jahre, 10 Monate von duschendestroyer
da hat jemand noch nicht Drezils seitenlange querys gesehen
wenn der die hier alle postet
gepostet vor 16 Jahre, 10 Monate von None
*G*
Meine sind nur noch recht kurz.
Ich bau entweder Views oder StoredProcedures.
Mache eh immer den "Fehler" zu viel Businesslogik in die Datenbank auszulagern.
gepostet vor 16 Jahre, 10 Monate von RaydenDD
Naja Businesslogik auszulagern mach ich eigentlich nicht gerne .. aber ich dacht mir bevor ich mit schon wieder nen Bein abprogrammieren muss, damit das ganze schnell geht, mach ichs mit nem einzigen Query
gepostet vor 16 Jahre, 10 Monate von Drezil
da im chat meine antwort ja schon heftig erwartet wurde *gg* hier mal eine kleine Query von mir.
Aus dem DB-log gezogen, also einfach uid und x/y-koord durch vars ersetzt denken:

select DISTINCT pl.sid, pl.pid,pl.uid,pl.pnr,so.x,so.y, pl.atmo,
COALESCE(f.status,CASE WHEN pl.uid=5 THEN 3 ELSE 0 END) as status,
so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) as p_x,
so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) as p_y,
pl.name as pname, u.name as username
from
game1.sonnen so
join game1.planeten pl on (pl.sid=so.sid)
left outer join game1.ffk f on (f.uid = pl.uid AND f.uida=5)
join game1.user_account u on (pl.uid=u.uid),
game1.gebaeude g
join game1.gebaeudereferenz gr on (g.gid = gr.gid)
join game1.planeten p on (g.pid=p.pid)
join game1.sonnen s on (s.sid=p.sid)
where
so.x between 3460 and 5040
AND so.y between 4960 and 6040
AND
pow(so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385)))-s.x-(p.pnr*cos(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385))),2)
+pow(so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385)))-s.y-(p.pnr*sin(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385))),2)
< case g.gid
when 50 then pow(500 - 500*pow(0.75,g.stufe),2)*g.prodfaktor*g.arbeiter/(gr.arbeiter*g.stufe)
when 51 then pow(1000 - 1000*pow(0.8,g.stufe),2)*g.prodfaktor*g.arbeiter/(gr.arbeiter*g.stufe)
when 52 then pow(750 - 750*pow(0.90,g.stufe),2)*g.prodfaktor*g.arbeiter/(gr.arbeiter*g.stufe)
when 53 then pow(1250 - 1250*pow(0.95,g.stufe),2)*g.prodfaktor*g.arbeiter/(gr.arbeiter*g.stufe)
end
AND p.uid=5
AND g.gid in (50,51,52,53)
AND so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) between 3500 and 5000
AND so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) between 5000 and 6000
UNION
select DISTINCT pl.sid, pl.pid,pl.uid,pl.pnr,so.x,so.y, pl.atmo,
COALESCE(f.status,CASE WHEN pl.uid=5 THEN 3 ELSE 0 END) as status,
so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) as p_x,
so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) as p_y,
pl.name as pname, u.name as username
from
game1.sonnen so
join game1.planeten pl on (pl.sid=so.sid)
left outer join game1.ffk f on (f.uid = pl.uid AND f.uida=5)
join game1.user_account u on (pl.uid=u.uid),
game1.sonden s
join game1.sondenreferenz sr on (s.typ = sr.typ)
where
so.x between 3460 and 5040 AND
so.y between 4960 and 6040 AND
pow(so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385)))-s.x,2)
+pow(so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385)))-s.y,2)
< CASE WHEN sr.sensor < sr.scanner THEN sr.scanner ELSE sr.sensor END
AND s.uid=5
AND so.x+(pl.pnr*cos(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) between 3500 and 5000
AND so.y+(pl.pnr*sin(unix_timestamp()*pl.bahnfaktor/(pl.pnr*13750.987083139757010431557155385))) between 5000 and 6000
die query wird zum beispiel ausgeführt, wenn wer in meinem navi zoomt. Und die ist auch recht fix durch.
Ich könnte das union mal zusammenfassen .. sollte die query nochmal um 30% beschleunigen.. atm braucht die ca. 150ms-300ms je nach last zum laufen... das ist mir noch zu viel.
gepostet vor 16 Jahre, 10 Monate von RaydenDD
oooooooook .... @Drezil ^^
gepostet vor 16 Jahre, 10 Monate von TheUndeadable
Mein 'Monster-Query' hält sich von der Komplexität arg in Grenzen, da für mich eine Datenbank nur eine dummer Datenspeichert ist:
CREATE OR REPLACE VIEW getmemberswithrangs AS 

SELECT
members.memberid AS memberid,
members.playerid AS playerid,
members.allianceid AS allianceid,
members.currentrang AS currentrang,
players.points AS points,
players.playername AS playername,
players.virginslastnight AS virginslastnight,
rangs.rangid AS rangid,
rangs.title AS rangtitle,
players.dragon_hugo+players.dragon_oskar+players.dragon_kunibert+
players.dragon_herbert+players.dragon_brutus+players.dragon_harald +
IF(SUM(troupmovements.dragon_hugo),SUM(troupmovements.dragon_hugo),0)+
IF(SUM(troupmovements.dragon_oskar),SUM(troupmovements.dragon_oskar),0)+
IF(SUM(troupmovements.dragon_kunibert),SUM(troupmovements.dragon_kunibert),0)+
IF(SUM(troupmovements.dragon_herbert),SUM(troupmovements.dragon_herbert),0)+
IF(SUM(troupmovements.dragon_brutus),SUM(troupmovements.dragon_brutus),0)+
IF(SUM(troupmovements.dragon_harald),SUM(troupmovements.dragon_harald),0)
AS dragonsum,
players.dragon_herbert+players.dragon_brutus+players.dragon_harald +
IF(SUM(troupmovements.dragon_herbert),SUM(troupmovements.dragon_herbert),0)+
IF(SUM(troupmovements.dragon_brutus),SUM(troupmovements.dragon_brutus),0)+
IF(SUM(troupmovements.dragon_harald),SUM(troupmovements.dragon_harald),0)
AS dragonsum_flying,
players.knight_basic+players.knight_advanced +
IF(SUM(troupmovements.knight_basic),SUM(troupmovements.knight_basic),0)+
IF(SUM(troupmovements.knight_advanced),SUM(troupmovements.knight_advanced),0) AS knights,
players.knight_advanced +
IF(SUM(troupmovements.knight_advanced),SUM(troupmovements.knight_advanced),0) AS knights_advanced
FROM members AS members
INNER JOIN players AS players ON players.playerid=members.playerid
LEFT JOIN troupmovements AS troupmovements ON troupmovements.playerid=members.playerid
LEFT JOIN rangs AS rangs ON members.currentrang=rangs.rangid
GROUP BY members.playerid;
Es gibt zwar längere Queries, die bestehen aber nur aus einer Auflistung von Spalten.

Auf diese Diskussion antworten