Avatar billede larsomania Nybegynder
07. august 2003 - 14:51 Der er 4 kommentarer og
2 løsninger

OrderBy giver ekstrem lang svartid

Hejsa,

Jeg har følgende query:

SELECT "OrderRep_OrderPartNr"."Invdate", "OrderRep_OrderPartNr"."TMSOrderPartNr", "OrderRep_OrderPartNr"."ConAmount", "OrderRep_OrderPartNr"."CompGroup", "OrderRep_OrderPartNr"."Account2", "OrderRep_OrderPartNr"."CompGroupName", "OrderRep_OrderPartNr"."CompGroupCurrency", "OrderRep_OrderPartNr"."Catname", "OrderRep_OrderPartNr"."Cap5OrderPartNr", "OrderRep_OrderPartNr"."Admonly"
FROM  "TMS_EPT"."dbo"."Captur50_OrderRep_PersonalRep" "OrderRep_OrderPartNr"
WHERE  "OrderRep_OrderPartNr"."CompGroup" LIKE 'ERC_UK' AND "OrderRep_OrderPartNr"."Admonly"='0' AND "OrderRep_OrderPartNr"."Invdate">={ts '2001-01-01 00:00:00'} AND "OrderRep_OrderPartNr"."Account2" LIKE '%'
ORDER BY "OrderRep_OrderPartNr"."Account2"


Hvor Captur50_OrderRep_PersonalRep er et view, der er en join på et andet view og tre tabeller. Det andet view er en Union af to selects på to tabeller.

Hvis jeg udfører forespørgslen UDEN Order By får jeg på 10 sekunder de 42514 rækker, der skal returneres. Hvis jeg laver Order By tager den en evighed (læs: mere end 10 minutter).

Jeg har forsøgt at lave et index på de oprindelige tabeller, der indeholder der felt, der sorteres på - det gjorde ikke nogen forskel.

Er der nogen, der har en ídé til hvordan det kan optimeres?

Jeg overvejer lidt at lægge en procedure ind, der kører selve forespørgslen uden Order By - og placerer resultatet i en midlertidig tabel, og kører selve rapporten ud fra den - det vil givetvis give bedre hastighed. Men jeg ville helt undvære denne midleritidge tabel, hvis muligt?

Nogen forslag??
Avatar billede codemonkey Nybegynder
07. august 2003 - 15:20 #1
Generelt kan UNION give problemer med ORDER BY. Overvej om du kan benytte UNION ALL, hvor alle rækker kommer med (også dubletter).

Hvis dette ikke hjælper, må du fyre op under din Query analyser og kikke lidt på Execution Plan.
Avatar billede trer Nybegynder
07. august 2003 - 16:14 #2
Prøv at give os kilden til de forskellige views også.
Avatar billede larsomania Nybegynder
07. august 2003 - 16:16 #3
Captur50_OrderRep_Personalrep:

SELECT      dbo.OrderRep_OldAndNew.Art, dbo.OrderRep_OldAndNew.Comp, dbo.OrderRep_OldAndNew.Account1,
                      dbo.OrderRep_OldAndNew.Account2, dbo.OrderRep_OldAndNew.ProductCode, dbo.OrderRep_OldAndNew.Supplier, dbo.OrderRep_OldAndNew.Dest,
                      dbo.OrderRep_OldAndNew.Createdate, dbo.OrderRep_OldAndNew.Depdate, dbo.OrderRep_OldAndNew.Retdate, dbo.OrderRep_OldAndNew.Invdate,
                      dbo.OrderRep_OldAndNew.FareAmount, dbo.OrderRep_OldAndNew.Acceptance, dbo.OrderRep_OldAndNew.CrsMethod,
                      dbo.OrderRep_OldAndNew.RoomCount, dbo.OrderRep_OldAndNew.Conference, dbo.OrderRep_OldAndNew.Carcomp,
                      dbo.OrderRep_OldAndNew.CarGroup, dbo.OrderRep_OldAndNew.LowPrice, dbo.OrderRep_OldAndNew.Okay, dbo.OrderRep_OldAndNew.PNRNo,
                      dbo.OrderRep_OldAndNew.Roomtype, dbo.OrderRep_OldAndNew.Tekst, dbo.OrderRep_OldAndNew.Shorttxt, dbo.OrderRep_OldAndNew.AreaName,
                      dbo.OrderRep_OldAndNew.FeeAmount, dbo.OrderRep_OldAndNew.Routing, dbo.OrderRep_OldAndNew.AcceptCode,
                      dbo.OrderRep_OldAndNew.AcceptTextDK, dbo.OrderRep_OldAndNew.AcceptTextEng, dbo.OrderRep_OldAndNew.CompName,
                      dbo.OrderRep_OldAndNew.CompGroup, dbo.OrderRep_OldAndNew.DestAir, dbo.OrderRep_OldAndNew.DestCountry,
                      dbo.OrderRep_OldAndNew.HtlName, dbo.OrderRep_OldAndNew.ProductName, dbo.OrderRep_OldAndNew.SupplierName,
                      dbo.OrderRep_OldAndNew.ConAmount, dbo.OrderRep_OldAndNew.ConCurrency, dbo.OrderRep_OldAndNew.ConDKKAmount,
                      dbo.OrderRep_OldAndNew.ConDKKFactor, dbo.OrderRep_OldAndNew.ConFactor, dbo.OrderRep_OldAndNew.ConLowPrice, dbo.Personalrep.Enavn,
                      dbo.Personalrep.Fnavn, dbo.Personalrep.Mnavn, dbo.Personalrep.Init, dbo.Personalrep.Longinit, dbo.Captur50_OrderPartNr.Allocname,
                      dbo.Captur50_OrderPartNr.Allocnum, dbo.Captur50_OrderPartNr.Amount, dbo.Captur50_OrderPartNr.Capuserid,
                      dbo.Captur50_OrderPartNr.Capusernum, dbo.Captur50_OrderPartNr.Catmethod, dbo.Captur50_OrderPartNr.Catname,
                      dbo.Captur50_OrderPartNr.Catseg1, dbo.Captur50_OrderPartNr.Catseg2, dbo.Captur50_OrderPartNr.Catsplitid, dbo.Captur50_OrderPartNr.Custom1,
                      dbo.Captur50_OrderPartNr.Custom2, dbo.Captur50_OrderPartNr.Custom3, dbo.Captur50_OrderPartNr.Debcre, dbo.Captur50_OrderPartNr.Department,
                      dbo.Captur50_OrderPartNr.Exportdate, dbo.Captur50_OrderPartNr.Paymethod, dbo.Captur50_OrderPartNr.Locname,
                      dbo.Captur50_OrderPartNr.Saechar4, dbo.Captur50_OrderPartNr.Saeflag1, dbo.Captur50_OrderPartNr.Stdaccexid,
                      dbo.Captur50_OrderPartNr.Submisdesc, dbo.Captur50_OrderPartNr.Submisname, dbo.Captur50_OrderPartNr.Tracountry,
                      dbo.Captur50_OrderPartNr.Transdate, dbo.Captur50_OrderPartNr.Transtype, dbo.Captur50_OrderPartNr.Tripname,
                      dbo.Captur50_OrderPartNr.Vendorname, dbo.Captur50_OrderPartNr.Exportid, dbo.CompGrp.Groupname AS CompGroupName,
                      dbo.CompGrp.Currency AS CompGroupCurrency, dbo.Captur50_OrderPartNr.OrderPartNr AS Cap5OrderPartNr,
                      dbo.OrderRep_OldAndNew.OrderPartNr AS TMSOrderPartNr, dbo.OrderRep_OldAndNew.CapVersion, dbo.Personalrep.Admonly
FROM        dbo.CompGrp INNER JOIN
                      dbo.OrderRep_OldAndNew ON dbo.CompGrp.Groupcode = dbo.OrderRep_OldAndNew.CompGroup LEFT OUTER JOIN
                      dbo.Captur50_OrderPartNr ON dbo.OrderRep_OldAndNew.OrderPartNr = dbo.Captur50_OrderPartNr.OrderPartNr LEFT OUTER JOIN
                      dbo.Personalrep ON dbo.OrderRep_OldAndNew.Init = dbo.Personalrep.Init
Avatar billede larsomania Nybegynder
07. august 2003 - 16:17 #4
OrderRep_OldAndNew:

SELECT    *
FROM        (SELECT    Orderrep.Ordernr + Orderrep.Partnr AS OrderPartNr, orderrep.Ordernr, orderrep.Partnr, orderrep.Cre_partnr, orderrep.Fak_kre, orderrep.Art,
                                              orderrep.Init, orderrep.InvoiceNo, orderrep.Comp, orderrep.Account1, orderrep.Account2, orderrep.Account3, orderrep.ProductCode,
                                              orderrep.Mcc, orderrep.Supplier, orderrep.Dest, orderrep.Createdate, orderrep.Depdate, orderrep.Retdate, orderrep.Invdate,
                                              orderrep.Tckexpire, orderrep.Tckreceive, orderrep.FareAmount, orderrep.Fare, orderrep.CarrGrant, orderrep.Commission, orderrep.Tax,
                                              orderrep.Fee, orderrep.Vat, orderrep.Crfee, orderrep.Crvat, orderrep.CompPrice, orderrep.FullFare, orderrep.Acceptance, orderrep.Agent,
                                              orderrep.Breakfast, orderrep.Carcomp, orderrep.Conference, orderrep.RoomCount, orderrep.Crs, orderrep.CrsMethod, orderrep.Dep_fak,
                                              orderrep.Dep_fak_ok, orderrep.Destcode, orderrep.DropOff, orderrep.Ext_apdate, orderrep.FOPayment, orderrep.CarGroup,
                                              orderrep.HandInv, orderrep.HandOrd, orderrep.Hidden, orderrep.HtlCRSReg, orderrep.Htlno, orderrep.InvDetails, orderrep.LowPrice,
                                              orderrep.Okay, orderrep.Pax, orderrep.PickUp, orderrep.PNRNo, orderrep.Requester, orderrep.Reqno, orderrep.Resref, orderrep.Returntrip,
                                              orderrep.Roomtype, orderrep.Serialno, orderrep.Shorttxt, orderrep.Tekst, orderrep.Tickettype, orderrep.Units, orderrep.LocalAmount,
                                              orderrep.CarKM, orderrep.BilledCur, orderrep.LocalCur, orderrep.Ext_aprovd, orderrep.Ext_fileid, orderrep.Ext_hold, orderrep.Ext_id,
                                              orderrep.AreaName, orderrep.FeeName, orderrep.AreaCode, orderrep.FeeAmount, orderrep.FeeNo, orderrep.Routing,
                                              orderrep.AirMileageTotal, orderrep.Flights, orderrep.AcceptCode, orderrep.AcceptTextDK, orderrep.AcceptTextEng, orderrep.CompName,
                                              orderrep.CompAdr, orderrep.CompZip, orderrep.CompCity, orderrep.CompCountry, orderrep.CompGroup, orderrep.DestAir, orderrep.DestCity,
                                              orderrep.DestState, orderrep.DestCountry, orderrep.HtlName, orderrep.HtlAddress, orderrep.HtlZip, orderrep.HtlCity, orderrep.HtlCountry,
                                              orderrep.FullName, orderrep.Account4, orderrep.Account5, orderrep.ProductName, orderrep.SupplierName, orderrep.CompGroupName,
                                              orderrep.Nofee, orderrep.Ratediff, orderrep.Ratelock, orderrep.Ratetrans, orderrep.MainCarrier, orderrep.BookingClass, orderrep.Fee2cap,
                                              orderrep.ProductLevel1, orderrep.ProductLevel1Name, orderrep.ProductLevel2, orderrep.ProductLevel2Name, orderrep.ProductAreaCode,
                                              orderrep.ProductAreaName, orderrep.Normalfare, orderrep.NormalFareIndex, orderrep.ConAmount, orderrep.ConCurrency,
                                              orderrep.ConDKKAmount, orderrep.ConDKKFactor, orderrep.ConFactor, orderrep.Card, orderrep.CapturaSend, orderrep.Fee2,
                                              Orderrep.ProductCode + Orderrep.Supplier AS ProductSupplier, LowPrice * ConFactor AS ConLowPrice, 4.1 AS CapVersion
                      FROM          TMS.dbo.Orderrep Orderrep
                      WHERE      (Orderrep.Createdate >= '01-01-2001') AND (SerialNo <> '-5')
                      UNION ALL
                      SELECT    Orderrep.Ordernr + Orderrep.Partnr AS OrderPartNr, orderrep.Ordernr, orderrep.Partnr, orderrep.Cre_partnr, orderrep.Fak_kre, orderrep.Art,
                                            orderrep.Init, orderrep.InvoiceNo, orderrep.Comp, orderrep.Account1, orderrep.Account2, orderrep.Account3, orderrep.ProductCode,
                                            orderrep.Mcc, orderrep.Supplier, orderrep.Dest, orderrep.Createdate, orderrep.Depdate, orderrep.Retdate, orderrep.Invdate,
                                            orderrep.Tckexpire, orderrep.Tckreceive, orderrep.FareAmount, orderrep.Fare, orderrep.CarrGrant, orderrep.Commission, orderrep.Tax,
                                            orderrep.Fee, orderrep.Vat, orderrep.Crfee, orderrep.Crvat, orderrep.CompPrice, orderrep.FullFare, orderrep.Acceptance, orderrep.Agent,
                                            orderrep.Breakfast, orderrep.Carcomp, orderrep.Conference, orderrep.RoomCount, orderrep.Crs, orderrep.CrsMethod, orderrep.Dep_fak,
                                            orderrep.Dep_fak_ok, orderrep.Destcode, orderrep.DropOff, orderrep.Ext_apdate, orderrep.FOPayment, orderrep.CarGroup,
                                            orderrep.HandInv, orderrep.HandOrd, orderrep.Hidden, orderrep.HtlCRSReg, orderrep.Htlno, orderrep.InvDetails, orderrep.LowPrice,
                                            orderrep.Okay, orderrep.Pax, orderrep.PickUp, orderrep.PNRNo, orderrep.Requester, orderrep.Reqno, orderrep.Resref, orderrep.Returntrip,
                                            orderrep.Roomtype, orderrep.Serialno, orderrep.Shorttxt, orderrep.Tekst, orderrep.Tickettype, orderrep.Units, orderrep.LocalAmount,
                                            orderrep.CarKM, orderrep.BilledCur, orderrep.LocalCur, orderrep.Ext_aprovd, orderrep.Ext_fileid, orderrep.Ext_hold, orderrep.Ext_id,
                                            orderrep.AreaName, orderrep.FeeName, orderrep.AreaCode, orderrep.FeeAmount, orderrep.FeeNo, orderrep.Routing,
                                            orderrep.AirMileageTotal, orderrep.Flights, orderrep.AcceptCode, orderrep.AcceptTextDK, orderrep.AcceptTextEng, orderrep.CompName,
                                            orderrep.CompAdr, orderrep.CompZip, orderrep.CompCity, orderrep.CompCountry, orderrep.CompGroup, orderrep.DestAir, orderrep.DestCity,
                                            orderrep.DestState, orderrep.DestCountry, orderrep.HtlName, orderrep.HtlAddress, orderrep.HtlZip, orderrep.HtlCity, orderrep.HtlCountry,
                                            orderrep.FullName, orderrep.Account4, orderrep.Account5, orderrep.ProductName, orderrep.SupplierName, orderrep.CompGroupName,
                                            orderrep.Nofee, orderrep.Ratediff, orderrep.Ratelock, orderrep.Ratetrans, orderrep.MainCarrier, orderrep.BookingClass, orderrep.Fee2cap,
                                            orderrep.ProductLevel1, orderrep.ProductLevel1Name, orderrep.ProductLevel2, orderrep.ProductLevel2Name, orderrep.ProductAreaCode,
                                            orderrep.ProductAreaName, orderrep.Normalfare, orderrep.NormalFareIndex, orderrep.ConAmount, orderrep.ConCurrency,
                                            orderrep.ConDKKAmount, orderrep.ConDKKFactor, orderrep.ConFactor, orderrep.Card, orderrep.CapturaSend, orderrep.Fee2,
                                            Orderrep.ProductCode + Orderrep.Supplier AS ProductSupplier, LowPrice * ConFactor AS ConLowPrice, 5.2 AS CapVersion
                      FROM        TMS_EPT.dbo.Orderrep Orderrep
                      WHERE    (Orderrep.Createdate >= '01-01-2001')) x
Avatar billede larsomania Nybegynder
07. august 2003 - 16:17 #5
Resten er tabeller
Avatar billede trer Nybegynder
07. august 2003 - 16:32 #6
Hurtigt kigget; dine OUTER JOINS forhindrer brug af index på de join kriterier, forskellig fra <> er heller ikke godt mht indeks og ligeledes vil din LIKE gøre brug af index besværlig (hvis ikke umulig).

Der er måske lidt at hente ved at placere et clustered index på orderrep.createdate og Account2. Generelt bør du gemme dit clustered indeks til en kolonne hvor du skal lave et range-select.

Problemet ved din UNION (ALL) er, at SQL Server skal opbygge hele tabellen i TEMPDB - på SQL Server 2000 sker det primært i RAM, hvis du har nok :-) og ellers på disk.

Du kan hjælpe lidt på ram forbruget ved kun at udtrække de kolonner du har behov for i de underliggende views - det minsker risikoen for at SQL Server skriver til fysisk disk.

En mulighed kan være, at du opbygger et indekseret view (det er reelt set en tabel bygget udfra din query som opdateres automatisk) - men det medfører andre problemer og bør kun benyttes hvis du kan leve med nogle begrænsninger i din frihed samt ikke opdaterer kildetabellerne særligt ofte.
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
Kategori
Computerworld tilbyder specialiserede kurser i database-management

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