SQL-запрос занимает слишком много времени - PullRequest
0 голосов
/ 27 марта 2012

Этот запрос занимает около 52 секунд.Похоже, 82% времени тратится на сканирование таблицы заказов.В нем говорится, что фактическое количество строк превышает 8 миллионов, поэтому я могу только предположить, что он циклически перебирает эту таблицу, и я недостаточно хорошо разбираюсь в SQL, чтобы понять, почему.

В таблице заказов в настоящее время имеется 19700 строк.

SELECT a.DistID, a.BusCtrID, d.FName, d.LName, r.Description 
FROM funcGetDownline( 3 , 1) a
INNER JOIN Distributor d ON a.DistID = d.DistID
INNER JOIN Rank r ON d.RankID = r.RankID
INNER JOIN Orders o ON o.DistID = d.DistID
INNER JOIN orderlines ol ON ol.OrderID = o.OrderID
GROUP BY a.DistID, a.BusCtrID, d.FName, d.LName, r.Description'

funcGetDownline возвращает одну таблицу, возвращающую 4 416 записей.Если я выполню запрос только к строке заказов, он вернет 15 361 строку, которая должна возвращать не более 4416.

Если я выполню запрос к строкам заказа, он вернет 20811 строк, опять же, он не долженвозвращать больше чем 4 416, меньше в порядке, но не больше.Он выполняет это за 1 секунду.

Когда я выполняю его до строки группы, выполнение этого запроса занимает около 50 секунд и возвращает 4 313 строк, что представляется правильным количеством строк.

Есть идеи, что я здесь делаю неправильно?

ВНОВЬ ИЗМЕНЕНО:

SELECT tmp.distid, tmp.busctrid, tmp.volume, r.description, d.fname, d.lname, d.email
FROM
(
SELECT o.Distid, o.busctrid, SUM (ol.volume * ol.quantity) as Volume
FROM Orders o
INNER JOIN Orderlines ol
 ON ol.orderid = o.orderid
GROUP BY o.distid, o.busctrid
HAVING SUM (ol.volume * ol.quantity) BETWEEN 0 AND 3011
)tmp
INNER JOIN Distributor d
 ON d.distid = tmp.distid
INNER JOIN Rank r
 ON r.rankid = d.rankid
INNER JOIN FuncGetDownline(3,1) a
 ON a.distid = tmp.distid
 AND a.busctrid = tmp.busctrid
ORDER BY tmp.DistID, tmp.BusCtrID 

Вышеупомянутый запрос выполняется за 1 секунду или менее, я не знаю, почему это так намного быстрее.Мой старший разработчик и я, вероятно, работали над этим в течение примерно 60 минут, настраивая его так, чтобы он был быстрым.

РЕДАКТИРОВ. ПОЛНЫЙ СПИСОК:

orders  PK_orders   Orderid
orders  PK_orders   Distid
orders  PK_orders   BusCtrID
orders  PK_orders   ShipAmt
orders  PK_orders   ShipDate
orders  PK_orders   ShipTrack
orders  PK_orders   TaxAmt
orders  PK_orders   invoicetype
orders  PK_orders   Notes
orders  PK_orders   PostAmount
orders  PK_orders   Status
orders  PK_orders   ShippingLine1
orders  PK_orders   ShippingLine2
orders  PK_orders   ShippingCity
orders  PK_orders   ShippingState
orders  PK_orders   ShippingCountry
orders  PK_orders   ShippingPostalCode
orders  PK_orders   EnteredBy
orders  PK_orders   PostFuturePeriod
orders  PK_orders   OrderDate
orders  PK_orders   MO_Ship
orders  PK_orders   ts
orders  PK_orders   ShippingPhone
orders  PK_orders   DatePaid
orders  PK_orders   PublicNotes
orders  PK_orders   LastUpdatedBy
orders  PK_orders   BonusDate
orders  PK_orders   TypeCode
orders  PK_orders   ShippingName
orders  PK_orders   GeoCode
orders  PK_orders   InOutCity
orders  PK_orders   TaxOption
orders  PK_orders   IsCredit
orders  PK_orders   TaxAmt2
orders  PK_orders   Aristo_Status
orders  PK_orders   WarehouseID
orders  PK_orders   ShipCost
orders  PK_orders   Weight
orders  PK_orders   Carrier
orders  PK_orders   Service
orders  PK_orders   OrderExported
orders  PK_orders   ShippingEmail
orders  PK_orders   CreditOrderID
orders  PK_orders   ShipMethod
orders  PK_orders   OrderID2
orders  PK_orders   PartyID
orders  PK_orders   ExportTimeStamp
orders  PK_orders   OrderIP
orders  PK_orders   PromoCode
orders  PK_orders   FirstOrder
Distributor Dist_PK DistID
Distributor Dist_PK Name
Distributor Dist_PK Status
Distributor Dist_PK Rank
Distributor Dist_PK OverRank
Distributor Dist_PK ORankDate
Distributor Dist_PK EnterDate
Distributor Dist_PK RenewalDate
Distributor Dist_PK Password
Distributor Dist_PK RankID
Distributor Dist_PK LName
Distributor Dist_PK FName
Distributor Dist_PK EnteredBy
Distributor Dist_PK MInitial
Distributor Dist_PK Email
Distributor Dist_PK RankDate
Distributor Dist_PK SSN
Distributor Dist_PK URL
Distributor Dist_PK HomePhone
Distributor Dist_PK WorkPhone
Distributor Dist_PK Fax
Distributor Dist_PK BillLine1
Distributor Dist_PK BillLine2
Distributor Dist_PK BillCity
Distributor Dist_PK BillState
Distributor Dist_PK BillPostalCode
Distributor Dist_PK BillCountry
Distributor Dist_PK ShipLine1
Distributor Dist_PK ShipLine2
Distributor Dist_PK ShipCity
Distributor Dist_PK ShipState
Distributor Dist_PK ShipPostalCode
Distributor Dist_PK ShipCountry
Distributor Dist_PK ts
Distributor Dist_PK FirstCycle
Distributor Dist_PK DistFlag1
Distributor Dist_PK DistFlag2
Distributor Dist_PK DistFlag3
Distributor Dist_PK DistFlag4
Distributor Dist_PK DistFlag5
Distributor Dist_PK DistFlag6
Distributor Dist_PK DistFlag7
Distributor Dist_PK HomePhoneExt
Distributor Dist_PK WorkPhoneExt
Distributor Dist_PK FaxExt
Distributor Dist_PK ExtraNumeric1
Distributor Dist_PK ExtraNumeric2
Distributor Dist_PK ExtraNumeric3
Distributor Dist_PK ExtraSring1
Distributor Dist_PK ExtraSring2
Distributor Dist_PK ExtraSring3
Distributor Dist_PK TaxExempt
Distributor Dist_PK txjr
Distributor Dist_PK GeoCode
Distributor Dist_PK InOutCity
Distributor Dist_PK DefaultWarehouse
Distributor Dist_PK TaxAsCustomer
Distributor Dist_PK CellPhone
Distributor Dist_PK PaidAsRank
Distributor Dist_PK TaxID
Distributor Dist_PK BankID
Distributor Dist_PK TrainerID
Distributor Dist_PK Statement
Distributor Dist_PK WebShowName
Distributor Dist_PK WebAddress
Distributor Dist_PK WebHomePhone
Distributor Dist_PK WebWorkPhone
Distributor Dist_PK WebFax
Distributor Dist_PK WebUrl
Distributor Dist_PK WebEmail
Distributor Dist_PK Photo
Distributor Dist_PK WebTemplate
Distributor Dist_PK HTMLEmail
Distributor Dist_PK UserDef1
Distributor Dist_PK UserDef2
Distributor Dist_PK UserDef3
Distributor Dist_PK UserDef4
Distributor Dist_PK UserDef5
Distributor Dist_PK UserDef6
Distributor Dist_PK UserDef7
Distributor Dist_PK UserDef8
Distributor Dist_PK UserDef9
Distributor Dist_PK UserDef10
Distributor Dist_PK UserDef11
Distributor Dist_PK UserDef12
Distributor Dist_PK UserDef13
Distributor Dist_PK UserDef14
Distributor Dist_PK UserDef15
Distributor Dist_PK EnableEcommerce
Distributor Dist_PK BirthDate
Distributor Dist_PK ModifiedBy
Distributor Dist_PK UserName
Distributor Dist_PK LastUpdateDate
Distributor Dist_PK ReceiveCompanyEmail
Distributor Dist_PK ReceiveUplineEmail
Distributor Dist_PK ReceiveUplineMessages
Distributor Dist_PK UserDef16
Distributor Dist_PK UserDef17
Distributor Dist_PK UserDef18
Distributor Dist_PK UserDef19
Distributor Dist_PK UserDef20
Distributor Dist_PK CreatedIP
Distributor Dist_PK UserDef21
Distributor Dist_PK UserDef22
Distributor Dist_PK UserDef23
Distributor Dist_PK OverrideMinChkAmt
Distributor Dist_PK ReceiveSponsorEmail
Distributor Dist_PK ReceiveDownlineActivityEmail
Distributor Dist_PK DefaultLanguage
Distributor Dist_PK DistID2
Distributor Dist_PK ImHandle
Distributor Dist_PK IMType
Distributor Dist_PK ReceivePersonallySponsoredActivityEmail
Distributor Dist_PK EnableWebsite
Distributor Dist_PK DistributorCenterExpireDate
Distributor Dist_PK WebsiteExpireDate
Distributor Dist_PK AutologinSessionID
Distributor Dist_PK RecoverPasswordKey
Distributor Dist_PK PCIUserID
Distributor Dist_PK TLPCountry
Distributor Dist_PK EncryptedSSN
Distributor Dist_PK EncryptedTaxID
Distributor Dist_PK AgreementAccepted
orderlines  PK_orderlines   OrderID
orderlines  PK_orderlines   OrderLineID
orderlines  PK_orderlines   ItemId
orderlines  PK_orderlines   Quantity
orderlines  PK_orderlines   Ship
orderlines  PK_orderlines   Amount
orderlines  PK_orderlines   Tax
orderlines  PK_orderlines   Weight
orderlines  PK_orderlines   StatusDate
orderlines  PK_orderlines   ShipDate
orderlines  PK_orderlines   Status
orderlines  PK_orderlines   Tracking1
orderlines  PK_orderlines   Tracking2
orderlines  PK_orderlines   RetailPrice
orderlines  PK_orderlines   WholesalePrice
orderlines  PK_orderlines   GroupItem
orderlines  PK_orderlines   Volume
orderlines  PK_orderlines   ts
orderlines  PK_orderlines   WarehouseID
orderlines  PK_orderlines   Notes
orderlines  PK_orderlines   ExtraCurrency1
orderlines  PK_orderlines   ExtraCurrency2
orderlines  PK_orderlines   ExtraCurrency3
orderlines  PK_orderlines   TaxRecID
orderlines  PK_orderlines   TrackingShipCo
orderlines  PK_orderlines   TaxRate
orderlines  PK_orderlines   MaxTaxAmt
orderlines  PK_orderlines   MaxOrderAmt
orderlines  PK_orderlines   CustomPrice
orderlines  PK_orderlines   DiscountPrice
orderlines  PK_orderlines   DiscountId
orderlines  PK_orderlines   DiscountDescription
orderlines  PK_orderlines   ShipCost
orderlines  PK_orderlines   Aristo_Status
orderlines  PK_orderlines   First_Time_Orderitem
orderlines  PK_orderlines   AttributeDetail
orderlines  PK_orderlines   Description
orderlines  PK_orderlines   BoxNumber

Ответы [ 4 ]

3 голосов
/ 27 марта 2012

Некоторые предложения:

  • Индексируются ли столбцы в предложении GROUP BY?Если нет, то это замедлит запрос.
  • Помечены ли столбцы «ID» как первичные ключи?Если нет, то они должны быть.Во многих современных СУБД столбцы, помеченные как первичный ключ, автоматически становятся индексами
  • Вы указали индексы для своих внешних ключей?Это a.DistID, d.rankID и т. Д. Если нет, то индексирование столбцов FK ускорит запрос
  • Использование функции, возвращающей таблицу, может быть не очень хорошей идеей.Если это выполняется в SQL Server, оптимизатор запросов не может оптимизировать эту часть запроса.

Надеюсь, это поможет.

3 голосов
/ 27 марта 2012

Причина увеличения количества записей в том, что внутренние объединения возвращают запись для КАЖДОГО совпадения.

IE.

Если у вас есть 1 ключ в ордерах и 5 совпадающих OrderID в линиях ордеров, вы получите 5 строк.

Таким образом, у вас может быть 4416 строк в одной точке, которые могут легко взорваться до гораздо более высоких чисел из-за объединений, а затем из-за группы вы получите ожидаемое число

EDIT

Try this query.  
  SELECT 
    T.Name as TableName, I.name as IndexName,s.name as IndexColumn
FROM 
    sys.indexes I 
INNER JOIN 
    Sys.tables t 
    ON 
        t.object_id = I.Object_ID 
inner join
    Sys.columns s
    on
        t.object_id = s.object_id
WHERE 
    index_id >= 1
    and
    t.type = 'U'

Это должно дать нам знать, где вы находитесь с индексами.

Также вы можете опубликовать сгенерированный план выполнения? Если вы выполняете запрос из SQL Server Management Studio, щелкните правой кнопкой мыши область написания запроса и выберите включить фактический план выполнения.

1 голос
/ 27 марта 2012

Я не уверен в этом, но, похоже, вам не нужны данные из заказов или строк заказов, а просто знать, что они существуют для этого запроса, поэтому ...

SELECT a.DistID, a.BusCtrID, d.FName, d.LName, r.Description  
FROM funcGetDownline( 3 , 1) a 
INNER JOIN Distributor d ON a.DistID = d.DistID 
INNER JOIN Rank r ON d.RankID = r.RankID 
where exists (select o.distid from  Orders o 
INNER JOIN orderlines ol ON ol.OrderID = o.OrderID 
where o.DistID = d.DistID )
1 голос
/ 27 марта 2012

Первое, что нужно проверить, это то, что у вас есть индексы для всех столбцов в предложении соединения.

во-вторых, ваш SQL указывает на группировку, поэтому перед 203 группировкой могут быть правильные числа 20К.

однако предложение group by обычно указывает на какой-то тип математики в группе, такой как функция sum (), которую я не вижу в вашем sql.вместо группы вы можете попробовать:

 SELECT DISTINCT a.DistID, a.BusCtrID, d.FName, d.LName, r.Description 
 FROM funcGetDownline( 3 , 1) a INNER JOIN Distributor d ON a.DistID =
 d.DistID INNER JOIN Rank r ON d.RankID = r.RankID INNER JOIN Orders o
 ON o.DistID = d.DistID INNER JOIN orderlines ol ON ol.OrderID =
 o.OrderID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...