请帮我以下查询进行优化。 "#盎司"临时表有16000行。现在这个查询运行大约14秒。
create table #oz (
id int, from_sto_move bit, product_id int, [date] datetime,
qty_orlogo decimal(30, 10), qty_zarlaga decimal(30, 10), cost_prev decimal(30, 10)
)
print 'Query started on: ' + CONVERT(nvarchar(30), GETDATE(), 126)
select
oz1.product_id,
oz1.id,
oz1.from_sto_move,
sum(isnull(oz2.qty_orlogo, 0) - isnull(oz2.qty_zarlaga, 0))
qty_oz,
oz1.cost_prev
from
#oz oz1 left join
#oz oz2 on
oz1.product_id = oz2.product_id and
oz1.[date] > oz2.[date]
group by oz1.product_id, oz1.id, oz1.from_sto_move, oz1.cost_prev
print 'Query finished on: ' + CONVERT(nvarchar(30), GETDATE(), 126)
我需要不到5秒钟。 感谢
答案 0 :(得分:0)
是否可以在列" product_id"上添加聚集索引到表中并包括" id"和" from_sto_move"在里面。如果有帮助,请告诉我。
你能在表格中添加另一个索引吗?
CREATE NONCLUSTERED INDEX [_dta_index_oz_7_148195578__K3_K1_K2_K7_4] ON [dbo].[oz]
(
[product_id] ASC,
[id] ASC,
[from_sto_move] ASC,
[cost_prev] ASC
)
INCLUDE ( [date]) WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
以下是您可以创建的第二个索引:
CREATE NONCLUSTERED INDEX [_dta_index_oz_7_148195578__K3_K4_5_6] ON [dbo].[oz]
(
[product_id] ASC,
[date] ASC
)
INCLUDE ( [qty_orlogo],
[qty_zarlaga]) WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
让我知道它的效果如何。
答案 1 :(得分:0)
我唯一的扩展建议是构建覆盖索引,但是引擎是否需要更多时间来准备索引而不是运行查询?
尝试在(product_id,[date],id,from_sto_move,cost_prev)上创建索引。
由于这是一个#temp表,我不认为使索引聚类是至关重要的,而不是仅仅拥有连接/组的关键元素。日期是加入的关键组成部分。
此外,您正在显示#oz的创建临时表,但不是如何填充它。也许从原始原始数据中填充它的一个级别可能也有助于准备一个预先排序的临时表,然后自我加入你正在寻找的结果。
答案 2 :(得分:0)
这似乎工作得很好,从我可以告诉它返回完全相同的结果(两个结果集的CHECKSUM_AGG(BINARY_CHECKSUM(*))
返回相同的值)。
;WITH src
AS (SELECT oz1.product_id,
oz1.id,
oz1.from_sto_move,
qty_oz = ISNULL((SELECT sum(isnull(oz2.qty_orlogo, 0) - isnull(oz2.qty_zarlaga, 0))
FROM #oz oz2
WHERE oz2.product_id = oz1.product_id
AND oz2.[date] < oz1.[date]), 0),
oz1.cost_prev
FROM #oz oz1)
SELECT product_id,
id,
from_sto_move,
sum(qty_oz) as qty_oz,
cost_prev
FROM src
GROUP BY product_id,
id,
from_sto_move,
cost_prev
&#39;伟大的&#39;关于它的事情是它不依赖于任何索引;事实上,它甚至可以直接在堆上运行,因此您不会浪费时间创建索引。
那就是说,即使桌子上没有真正的PK(临时表还是没有);我始终确保在创建表格时至少添加IDENTIY()
列,并在 加载数据之前将聚簇索引放在上。根据我的经验,它可以加快数据加载速度。