webForumDet fria alternativet

Trimma en SP ordentligt

Databaser & SQL

13 svar · 332 visningar · startad av Brimba

Medlem sedan dec. 19995 874 inlägg
Frågan#1

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
Medlem sedan dec. 200012 464 inlägg
#2

Vilka kolumner är indexerade? Går det fortare om du tar bort top 10?

Har du tittat på ekveringsplanen?

Medlem sedan dec. 19995 874 inlägg
#3

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?

Medlem sedan dec. 200012 464 inlägg
#4

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

Medlem sedan dec. 19995 874 inlägg
#5

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?

Medlem sedan aug. 20003 575 inlägg
#6

Vad är det för server, den kanske är slö :stud

Medlem sedan dec. 19995 874 inlägg
#7

Ja rätt slö server är det. Intel Celeron 600, 256 MB RAM

Medlem sedan dec. 19995 874 inlägg
#8

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?

Medlem sedan dec. 200012 464 inlägg
#9

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

Medlem sedan dec. 19995 874 inlägg
#10

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?

Medlem sedan dec. 19995 874 inlägg
#11

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?

Medlem sedan dec. 200012 464 inlägg
#12

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.

Medlem sedan dec. 19995 874 inlägg
#13

Spelar det någon roll hur stort betweenvärde jag anger?

exempelvis:

and bytessent between 0 and 2000000000000000000

skulle det hjälpa ens lite?

Medlem sedan maj 2001431 inlägg
#14

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.

264 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
130 ms — deklarationer (db)
0 ms — hämta statistik (cache)
131 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)