Avatar billede orca Nybegynder
08. februar 2008 - 10:34 Der er 7 kommentarer og
2 løsninger

Optimering af query

Jeg har en tabel indeholdende en masse rækker som hver tilhører et givent PageID (relation til anden tabel).

Jeg skal regelmæssigt køre en query som sørger for at kun de sidste 200 rækker for hvert PageID forbliver i tabellen, dvs. alle rækker udover de seneste 200 indsatte, for et givent PageID, skal slettes. Min nuværende query er i store træk som følgende:

DELETE FROM tblSomeTable WHERE ClickID NOT IN (SELECT TOP 200 ST.ClickID FROM tblSomeTable ST WHERE ST.PageID = tblSomeTable.PageID ORDER BY ST.ClickID DESC)

Jeg vil gerne have den effektiviseret da den ikke er voldsomt hurtig som det er i dag.

Jeg har clustered index på ClickID og et nonclustered index på PageID.
Avatar billede orca Nybegynder
08. februar 2008 - 10:44 #1
Jeg fik vidst lige sendt den basale query, kører en lidt mere optimeret form:

SELECT ClickID FROM tblSomeTable WHERE PageID IN (SELECT PageID FROM tblSomeTable GROUP BY PageID HAVING COUNT(1) > 200) AND ClickID NOT IN (SELECT TOP 200 ST.ClickID FROM tblSomeTable ST WHERE ST.PageID = tblSomeTable.PageID ORDER BY ST.ClickID DESC)
Avatar billede orca Nybegynder
08. februar 2008 - 10:45 #2
Og der kan SELECT så byttes ud med DELETE :)
Avatar billede terry Ekspert
08. februar 2008 - 10:46 #3
Just an idea as I'm not quite sure how SQL server does this.
Try changing the sub select to a derived table and then make a join from the outer select to the derived table.
I know that Access mnakes teh sub select for every row which is time consuming.

Also concider putting the SQL into a stored procedure which might also help.
Avatar billede orca Nybegynder
08. februar 2008 - 10:57 #4
Efter at have droppet mit nonclustered index og oprettet et nyt over (PageID ASC, PointClickID DESC) så er jeg sluppet væk med næsten alt arbejdet ved TOP 200 selecten da det lå i SORTen.

Terry, jeg vil lige prøve at eksperimentere med joinet.
Avatar billede orca Nybegynder
08. februar 2008 - 11:10 #5
Terry, efter at have studeret execution planen kan jeg se at subselecten ikke udgør et probm. Ved sidstnævnte query og det nye index så ligger 75% af tiden i et Index Seek i TOP 200 querien, dvs. det er min WHERE ST.PageID = tblSomeTable.PageID der tager det primære arbejde p.t. Men allerede på nuværende tidspunkt er den optimeret væsentligt ifh.t. udgangspunktet.
Avatar billede terry Ekspert
08. februar 2008 - 11:24 #6
The "..WHERE ST.PageID = tblSomeTable.PageID .." is in the sub select so you may still find that a sub select might help
Avatar billede orca Nybegynder
08. februar 2008 - 12:35 #7
Jeg har både forsøgt at fyre HAVING clausen ud som en CTE og sidste subquery ud som en derived table, begge giver præcis samme execution plan så jeg tror MSSQL'en optimerer til det samme bagved :)

Jeg tror jeg takker og lukker :)
Avatar billede terry Ekspert
08. februar 2008 - 12:42 #8
selv tak og god weekend
Avatar billede dr_chaos Nybegynder
08. februar 2008 - 16:47 #9
Normalt kan de næsten aldrig anbefale at bruge en subselect.
Min personlige løsning ville være at gøre det på denne måde:
DELETE FROM tblSomeTable t WHERE t.ClickID
LEFT JOIN  (SELECT TOP 200 ST.ClickID FROM tblSomeTable ST WHERE ST.PageID = tblSomeTable.PageID ORDER BY ST.ClickID DESC) x ON X.ClickId=t.ClickID
WHERE  X.ClickId IS NULL
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester