On Wed, 29 Aug 2001 22:54:06 +0200, Christian Schmidt
<christian@schmidt.net> wrote:
>Jeg kender ikke alverden til nested SELECTs, men det foresvæver mig, at
>man vil kunne kombinere UPDATE og SELECT i ét udtryk. Dette vil nok ikke
>ændre alverden på den teoretiske beregningskompleksitet, men køretiden
>vil nok mindskes betragteligt pga. det stærkt reducerede antal kald til
>databasen.
.... med fare for netop at lyde praktisk og uteoretisk i forhold til
resten af dit indlæg, så forekommer det mig at der (selvfølgelig ikke
overraskende) er meget ved at vinde med simple tricks og
"så-gør-vi-også-lige-det-i-samme-omgang"-stunts.
Mit nuværende setup er altså fortløbende at hive
resultater/person-id's ud - der foretages en query pr. trin, og hver
query er altså identisk, bortset fra at der er hældt flere folk til.
Vi skal finde ud af hvem person-id 245 er forbundet til:
SELECT [.. diverse data ..]
FROM asrel AS t1, asrel AS t2, sce
WHERE t1.aut_id IN (245)
[.. alle relationer frem og tilbage ..]
AND t2.aut_id NOT IN (245)
GROUP BY fundetperson
Ud fra denne query får vi så fx id 60 og 221, som altså er forbundet.
Query'en i næste trin vil så være:
SELECT [.. diverse data ..]
FROM asrel AS t1, asrel AS t2, sce
WHERE t1.aut_id IN (60,221)
[.. alle relationer frem og tilbage ..]
AND t2.aut_id NOT IN (245,60,221)
GROUP BY fundetperson
Herfra finder vi måske kun én person, nr. 59, og vores næste query vil
så være:
SELECT [.. diverse data ..]
FROM asrel AS t1, asrel AS t2, sce
WHERE t1.aut_id IN (59)
[.. alle relationer frem og tilbage ..]
AND t2.aut_id NOT IN (245,60,221,59)
GROUP BY fundetperson
.... og så fremdeles. Altså meget, meget enkelt at hælde ind i en
simpel løkke i sit FavoritSprog. Førstnævnte relation vil pege på "dem
netop fundet sidst", og sidstnævnte vil indeholde en tiltagende
udelukkelses-liste.
Min erfaring hermed er, at "lange tråde" (altså med mange rækker) ikke
er specielt slemme, men findes der mange personer i starten (også
selvom de mange nye personer ikke har flere at være koblet sammen
med), vil det være lidt tungt her. Det er klart, at den tiltagende
"NOT IN"-liste vil sætte krav til database-systemets opbygning. Her
forekommer det mig, at MySQL let piver over det stigende antal rows,
der skal "tages højde for", alene pga. den efterhånden lange "NOT
IN"-liste. I mit tilfælde er det ikke det større problem, da en person
kun typisk er forbundet til 0-3 andre, men i et film-tilfælde, vil en
sådan liste hurtigt eksplodere.
Eneste, jeg pt. ikke er så begejstret for (udover at mit datamateriale
ikke har så mange forfattere, der har links til hinanden) er, at man
vel egentligt godt kan betragte det som en lille smule redundans, at
der hele tiden bruges den samme NOT-liste, bare "lidt større" ved hver
query. Jeg kunne måske overveje noget med at arbejde med en temp-kopi
af databasen, og så fjerne entries på den hårde måde i stedet for.
Problemet, som jeg ser det nu, er, at hvis der i første omgang kommer
for mange med på den NOT-liste alt for tidligt, så skal databasen
trækkes med at der gang på gang vil være alt det at "tage højde
for"...
En simpel opgradering fra MySQL 3.22 til 3.23 (og fra ISAM til
MyISAM), hjalp i øvrigt gevaldigt på føromtalte sløvhed, og jeg har
klart på fornemmelsen, at det kan optimeres en del mere vha. simple
ting (evt. forsøge at lave noget read-only-adgang, m.m.). Jeg har dog
ikke løbende benchmarket så meget, som jeg burde, men i mit tilfælde
er tiderne i praksis klart til at leve med. For sjov lavede jeg endnu
en løkke uden om det almindelige setup, så i stedet for bare at finde
en persons "tråd", forsøgte jeg at finde længden på hver enkelt
persons tråd - dvs. knap 300 personer, hvilket gav i alt 575 queries
(hvor en normal person svinger mellem 0 og 6 led/queries). På mit
simple hjemmecomputer-system tager dette en 6-7 sekunder, hvilket,
igen i mit tilfælde, absolut er tilfredsstillende for at lave en
gennemgang, knap 300 gange.
Mit nuværende "problem" er dog næsten lidt pinligt, men jeg er i tvivl
om hvordan, jeg kan gøre det på den mest optimale måde, når jeg i en
query endelig finder den, der skal matches med (i tilfælde af at man
vælger to personer, og bare starter fra den ene). Altså, i og med at
jeg jo har en query i en løkke, så kan jeg godt risikere at jeg
befinder mig i "tredje gennemkørsel/cirkel/query", uden al information
fra før. Så når jeg endelig finder ud af at "29" har "100" (som måske
var ham, vi skulle finde) i sin inderkreds, hvordan finder jeg så ud
af, hvordan jeg i første omgang fandt frem til 29? For mig lugter det
umiddelbart af at man gemmer hver evige eneste row i alle sine
resultater...
>Derudover er jeg netop hjemvendt fra USA og har pga. rejse og
>tidsforskel ikke sovet alverden det sidste 1½ døgn, så jeg er lidt træt
>i mit hoved
Øv, jeg kan kun stille med netop at være hjemvendt fra London og knap
så mange timers "oppetid"
--
- Peter Brodersen