04. september 2007 - 09:51Der er
4 kommentarer og 1 løsning
Optimere query på SQL Server
Se engang denne query:
====================================== Select * From DeliveryAddressPendingUpdate Where DeliveryAddressPendingUpdateId Not In (Select DeliveryAddressPendingUpdateId From DeliveryAddressProcessedUpdate Where ApplicationServiceId = 2001) And PriorityNumber = 1 And DeliveryAddressPendingUpdateId >= 89749 And ( DeliveryAddressId > 0 ) And Not DeliveryAddressId in (select DeliveryAddressId from TraceAmadeusDeliveryAddressError) Order By DeliveryAddressId, DeliveryAddressPendingUpdateId DESC; ======================================
Mit problem er "Select DeliveryAddressPendingUpdateId From DeliveryAddressProcessedUpdate Where ApplicationServiceId = 2001" midt inde i querien - antallet af records i tabellen vokser og vokser - og der allokeres jo rigtig meget RAM hver gang.
Forespørgslen udføres hyppigt så jeg ville meget gerne optimere den, min udvikler kan ikke lige finde ud af hvad han skal gøre ved den.
prøv med noget i denne stil (simplificeret) Select * From DeliveryAddressPendingUpdate d Where NOT EXISTS(Select 1 From DeliveryAddressProcessedUpdate da Where ApplicationServiceId = 2001 AND da.DeliveryAddressPendingUpdateId = d.DeliveryAddressPendingUpdateId ) AND NOT EXISTS (select DeliveryAddressId from TraceAmadeusDeliveryAddressError t WHERE t.DeliveryAddressId = d.DeliveryAddressId ) Order By DeliveryAddressId
Der kan være sql fejl. Men not exists performer bedre ved mange records.
Da der i begge tilfælde er tale om en Not In subselect, burde den relativt enkelt kunne omskrives til en join i stedet. Det burde gøre, at den kører noget hurtigere, især hvis indexerne er på plads. Prøv at teste denne her:
Select pend.* From DeliveryAddressPendingUpdate pend Left Join DeliveryAddressProcessedUpdate proc ON proc.DeliveryAddressPendingUpdateId = pend.DeliveryAddressPendingUpdateId And proc.ApplicationServiceId = 2001 Left Join TraceAmadeusDeliveryAddressError aerr ON aerr.DeliveryAddressId = pend.DeliveryAddressId Where pend.DeliveryAddressId > 0 And pend.PriorityNumber = 1 And proc.proc.DeliveryAddressPendingUpdateId Is Null And aerr.DeliveryAddressId Is Null Order By pend.DeliveryAddressId, pend.DeliveryAddressPendingUpdateId DESC
Jeg har sat et par korte aliaser på tabellerne, da deres navne er noget lange at bakse rundt med.
Hov der er en dobbelt proc. i where delen. Det er naturligvis en fejl.
SELECT pend.* FROM DeliveryAddressPendingUpdate pend LEFT JOIN DeliveryAddressProcessedUpdate proc ON proc.DeliveryAddressPendingUpdateId = pend.DeliveryAddressPendingUpdateId AND proc.ApplicationServiceId = 2001 LEFT JOIN TraceAmadeusDeliveryAddressError aerr ON aerr.DeliveryAddressId = pend.DeliveryAddressId WHERE pend.DeliveryAddressId > 0 AND pend.PriorityNumber = 1 AND proc.DeliveryAddressPendingUpdateId IS NULL AND aerr.DeliveryAddressId IS NULL ORDER BY pend.DeliveryAddressId, pend.DeliveryAddressPendingUpdateId DESC
Jeg fik ændret den til et join og det gav betemt en meget markant forbedring af resourceforbruget. Tak for hjælpen. KJUlius, hvis du poster en besked som svar er pointene dine.
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.