我正在努力加快执行时间。我的查询有什么问题。什么是更好的查询优化方法。
TransactionEntry有2百万条记录
交易表有50亿条记录
以下是我的查询,如果我删除了 TotalPrice 列,我的结果是 10秒
--Total Quantity
SELECT
items.ItemLookupCode,sum(transactionsEntry.Quantity) Quantity,sum(transactionsEntry.Quantity*transactionsEntry.Price) TotalPrice
into
##temp_TotalPrice
FROM
(
SELECT
TransactionNumber,StoreID,Time
FROM
[HQMatajer].[dbo].[Transaction]
WHERE
Time>=CONVERT(datetime,'2015-01-01 00:00:00',102) and Time<=CONVERT(datetime,'2015-12-31 23:59:59',102)
) transactions
left join [HQMatajer].[dbo].[TransactionEntry] transactionsEntry
ON transactionsEntry.TransactionNumber=transactions.TransactionNumber and transactionsEntry.StoreID=transactions.StoreID
Left join [HQMatajer].[dbo].[Item] items
ON transactionsEntry.ItemID=items.ID
Group By items.ItemLookupCode
Order by items.ItemLookupCode
如果我执行此(上面一个)查询,它会在 22秒中生成结果。它太长了
当我单独执行子查询时(下面一个)。这需要11秒
(
SELECT
TransactionNumber,StoreID,Time
FROM
[HQMatajer].[dbo].[Transaction]
WHERE
Time>=CONVERT(datetime,'2015-01-01 00:00:00',102) and Time<=CONVERT(datetime,'2015-12-31 23:59:59',102)
) transactions
我为
的索引TransactionEntry Table
创建了一个
- 醇>
TransactionNumber,StoreID,ItemID,Quantity,Price
的一个索引
Transaction Table
`Time,TransactionNumber,StoreID`
的一个索引
Item Table
`ID`
TransactionEntry的Clustured Index需要花费59%的成本。该column_Name为
AutoID
答案 0 :(得分:1)
假设这是针对SQL 2005或更高版本的。如果它用于SQL 2000,那么您可以使用具有适当索引的CTE
表而不是temp
。
此外,由于您从[HQMatajer].[dbo].[TransactionEntry]
和[HQMatajer].[dbo].[Item]
获取了值,为什么要使用左连接?
避免子查询。我已经重新构建了查询。请检查并告诉我它是否改善了性能
;WITH transactions
AS
(
SELECT
TransactionNumber,StoreID,Time
FROM
[HQMatajer].[dbo].[Transaction]
WHERE
Time>=CONVERT(datetime,'2015-01-01 00:00:00',102) and Time<=CONVERT(datetime,'2015-12-31 23:59:59',102)
)
SELECT
items.ItemLookupCode,sum(transactionsEntry.Quantity) Quantity,sum(transactionsEntry.Quantity*transactionsEntry.Price) TotalPrice
into
##temp_TotalPrice
FROM [HQMatajer].[dbo].[Item] items INNER JOIN [HQMatajer].[dbo].[TransactionEntry] transactionsEntry
ON transactionsEntry.ItemID=items.ID
WHERE EXISTS (SELECT 1 FROM transactions WHERE transactionsEntry.TransactionNumber=transactions.TransactionNumber and transactionsEntry.StoreID=transactions.StoreID)
Group By items.ItemLookupCode
Order by items.ItemLookupCode
答案 1 :(得分:1)
这是您的查询,简化并格式化了一点(子查询没有区别):
select i.ItemLookupCode,
sum(te.Quantity) as quantity,
sum(te.Quantity * te.Price) as TotalPrice
into ##temp_TotalPrice
from [HQMatajer].[dbo].[Transaction] t left join
[HQMatajer].[dbo].[TransactionEntry] te
on te.TransactionNumber = t.TransactionNumber and
te.StoreID = t.StoreID left join
[HQMatajer].[dbo].[Item] i
on te.ItemID = i.ID
where t.Time >= '2015-01-01' and
t.Time < '2016-01-01'
group by i.ItemLookupCode
order by i.ItemLookupCode;
对于此查询,您需要Transaction(Time, TransactionNumber, StoreId)
,TransactionEntry(TransactionNumber, StoreId, ItemId, Quantity, Price)
和Item(Id,ItemLookupCode)上的索引`。
即使使用正确的索引,这也会处理大量数据,因此如果将时间缩短到几秒钟,我会感到惊讶。
答案 2 :(得分:0)
这个查询花费了很多时间,因为三次将条目插入临时表中会增加时间。如果我们将记录插入另一个表中并将其调用或将其作为cte。它降低了成本。