需要优化mssql查询以获得最快速度

时间:2014-08-06 09:52:56

标签: sql sql-server indexing query-optimization

请帮我以下查询进行优化。 "#盎司"临时表有16000行。现在这个查询运行大约14秒。

DOWNLOAD QUERY WITH DATA

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秒钟。 感谢

3 个答案:

答案 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()列,并在 加载数据之前将聚簇索引放在上。根据我的经验,它可以加快数据加载速度。