Vilka kolumner är indexerade? Går det fortare om du tar bort top 10?
Har du tittat på ekveringsplanen?
13 svar · 334 visningar · startad av Brimba
Hej!
Jag har följande SP
Egentligen en helt vanlig fråga, men hur skall jag indexera mina tabeller på SQLServer för att denna fråga skall gå fort att ställa?
Frågan tar mellan 15-45 sekunder att köra!!! Den körs på en SQLServer 7.0 databas.
Det är ungefär 200 000 poster i databasen, men varför tar det så lång tid?
Skall man ställa enklare frågor och köra union och sedan urvalsfråga, eller köra ner olika frågor i temporära tabeller?
Hur skulle ni ha gjort? Ändra gärna i min fråga. Men som sagt, ett ordentligt index kanske kan hjälpa, men isåfall vill jag veta hur det skall se ut.
SELECT TOP 10
tblLog.Target AS filename,
Count(tblLog.Target) AS countSum
FROM
tblLog
WHERE
tblLog.ServiceStatus=226
AND tblLog.ProcessingTime<>0
AND tblLog.BytesSent>0
AND Len(tblLog.Target)>2
GROUP BY
tblLog.Target
ORDER BY
Count(tblLog.Target) DESC,
tblLog.Target ASC
Vilka kolumner är indexerade? Går det fortare om du tar bort top 10?
Har du tittat på ekveringsplanen?
Vilka kolumner är indexerade?
Jag har indexerat Target, BytesSent, ProcessingTime och ServiceStatus
Jag har även provat helt utan index.
Går det fortare om du tar bort top 10?
Nej
Har du tittat på ekveringsplanen?
Ja.
SELECT COST : 0%
TOP COST : 0%
SORT COST : 0%
HASG MATCH/AGGREGATE COST : 6%
FILDER COST : 5%
INDEX SEEK COST : 88%
Skall detta verkligen ta så lång tid alltså? Det är helt normalt?
Hur stor selektivitet har du? Dvs hu många poster uppfyller villkoren (speciellt ServiceStatus=226)?
Har du ett sammansatt index eller flera olika?
Jag skulle nog sätta ett klustrat (eventuellt sammasatt med processingtime eller bytessent) index på ServiceStatus men inte indexera någon annan kolumn.
Update statistics -- efter indexskapandet
Det hjälper dessvärre inte så mycket.
Var hittar jag "update statistics"? Jag hittar bara det när jag ställer in min maintence plan, men det är väl inte där?
Vad är det för server, den kanske är slö :stud
Ja rätt slö server är det. Intel Celeron 600, 256 MB RAM
Kan man inte ställa frågan i flera etapper?
På det sättet skulle man kunna ställa order och group i slutet. Det kanske blir några färre poster i alla fall.
Tips?
Hur är det med selektiviteten? Om det finns 100000 poster där servicestatus = 226 så har ett index inte så stor betydelse.
Hur är data fördelat i de andra kolumnerna? Det har betydelse om du gör ett sammansatt index eller inte.
Update statistics:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ca-co_5t9v.asp
68 897 (med alla)
137 275 (med ServiceStatus)
119 648 (med ProcessingTime)
72 707 (med BytesSent)
175 033 (med len(Target>2))
186 009 (helt utan)
Så det verkar vara BytesSent som skall indexeras eller?
Vill du samtidigt förklara skillnaden på ett klustrat index, jämfört med ett "vanligt". Alltså vid vilka tillfällen är det en fördel att använda ett klustrat index?
Men trots allt så har jag fortfarande 68 897 poster som sedan skall grupperas och sorteras.. Det är inte så bra eller?
Finns det något sätt att cacha frågor under kanske 10 minuter? Vilket medför att alla frågor som ställs återigen inom den tidsperioden så returneras samma svar som innan?
Ett klustrat index innebär att datablocken ligger i ordning enligt de indexerade kolumnerna. Ett icke klustrat index innehåller bara referenser till datablocken.
Så om man har ett intervall som man vill söka inom så är ett klustrat index bättre. Kan du skriva villkoret for bytessent som ett slutet intervall?
and bytessent between 0 and 2000
Nu vet jag inte exakt hur sql server fungerar men andra dbms kan vara mer benägna att använda index om man har ett slutet intervall.
Bytessent ser ut som bästa kandidaten att indexera men om det är så stora datamängder som skall aggrgeras så är det svårt att få riktigt bra fart på frågan.
Du kan ju ha en extra tabell där du lagrar resultatet med en datetime kolumn om den är för gammal så tömmer du tabellen och kör om frågan.
Spelar det någon roll hur stort betweenvärde jag anger?
exempelvis:
and bytessent between 0 and 2000000000000000000
skulle det hjälpa ens lite?
Min gissning är att det är villkoret
Len(tblLog.Target)>2
som är prestandtjuven. Resten är ju elementärt för en tabell med poster, trots GROUP BY.