如何改善此SQL的执行时间
declare @Nemo as varchar(30)
set @Nemo = 'TELH14F'
UPDATE Nemos
SET MPV = px,
SaleContracts = SC
FROM (SELECT TOP 1 sum (Qty) SC,
Px
FROM marketState
WHERE Nemo = @Nemo
AND side = 2
GROUP BY Px
ORDER BY px) src
WHERE Nemo = @Nemo
UPDATE Nemos
SET MPC = px,
BuyContracts = SC
FROM (SELECT TOP 1 sum (Qty) SC,
Px
FROM marketState
WHERE Nemo = @Nemo
AND side = 1
GROUP BY Px
ORDER BY px DESC) src
WHERE Nemo = @Nemo
我尝试在同一个表Nemos上合并这两个更新并更改"选择前1"到MAX或MIN功能没有成功
编辑 - 已添加</ strong>
我还查看了此查询的执行计划,这就是我询问如何改进它的原因
目标是只选择/读取一次MarketState表,并将两个更新合并为一个。
与此类似的东西
update Nemos SET MPV = pxV , SaleContracts =SC, MPC = pxC, BuyContracts =BC
FROM
(Select top 1 sum (Qty) as SC, px as pxV
from marketState where Nemo = @Nemo and side=2
group by Px order by px ) srcA
-- UNION ALL--
(Select top 1 sum (Qty) as BC, Px as pxC
from marketState where Nemo = @Nemo and side=1
group by Px order by px desc ) srcB
where Nemo = @Nemo
如何使用MIN
,MAX
方法避免使用该UNION或使其工作(请记住列Qty
已加总,但列px
为不)
这些是表格和指标创作脚本
CREATE TABLE [dbo].[Nemos](
[Nemo] [varchar](50) NOT NULL,
[Description] [varchar](50) NULL,
[ProductId] [varchar](10) NULL,
[ExpirationDate] [datetime] NULL,
[CurrentValue] [numeric](21, 5) NULL,
[SaleContracts] [int] NULL,
[MPV] [numeric](21, 5) NULL,
[BuyContracts] [int] NULL,
[MPC] [numeric](21, 5) NULL,
[Active] [bit] NULL,
[ContractQuantity] [numeric](18, 2) NULL,
[NemoFactor] [int] NULL,
[MinFactor] [numeric](6, 2) NULL,
[Factor] [numeric](6, 2) NULL,
[Delta] [numeric](6, 2) NULL,
[TipoDelta] [varchar](5) NULL,
[ContractType] [varchar](50) NULL,
[FinalTradingDate] [datetime] NULL,
[CompGroup] [varchar](50) NULL,
[TypeDelivery] [varchar](5) NULL,
[Decimals] [int] NULL,
[BeginTradingDate] [datetime] NULL,
[PxRef] [numeric](21, 5) NULL,
[BuyQty] [int] NULL,
[SaleQty] [int] NULL,
[LastUpdate] [datetime] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Nemos] ADD DEFAULT (getdate()) FOR [BeginTradingDate]
GO
ALTER TABLE [dbo].[Nemos] ADD DEFAULT (getdate()) FOR [LastUpdate]
GO
/****** TABLE NEMOS INDEXES ******/
CREATE NONCLUSTERED INDEX [Nemos_Nemo] ON [dbo].[Nemos]
(
[Nemo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/***************************** marketState **************/
CREATE TABLE [dbo].[marketState](
[Nemo] [varchar](50) NULL,
[OrderNumber] [varchar](50) NULL,
[Px] [numeric](21, 5) NULL,
[Qty] [int] NULL,
[side] [int] NULL,
[owner] [varchar](50) NULL,
[LastUpdate] [datetime] NULL,
[Consecutivo] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_marketState] PRIMARY KEY CLUSTERED
(
[Consecutivo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
/****** MARKETSTATE STATE INDEXES ******/
ALTER TABLE [dbo].[marketState] ADD CONSTRAINT [PK_marketState] PRIMARY KEY CLUSTERED
(
[Consecutivo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [Nemo_Side] ON [dbo].[marketState]
(
[Nemo] ASC,
[side] ASC
)
INCLUDE ( [Px],
[Qty]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [MS_OrderNumber] ON [dbo].[marketState]
(
[OrderNumber] ASC
)
INCLUDE ( [owner]) WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
GO
核心思想是计算衍生物的 BestBuyingPrice = MPC 和 BestSellingPrice = MPV (nemo..tecnico)。
当 Side = 1 时,其购买订单,当 Side = 2 时,其 SellingOrder
当两个或多个订单的价格完全相同时,需要添加其数量(总和) 见下图
答案 0 :(得分:1)
正如我在评论中提到的,检查按行和ASC / DESC子句的顺序是否正确,如果在下面的查询中没有相应更新。
还要确保您有更新的索引
表市场状态:
CREATE CLUSTERED INDEX CIDX_marketState ON marketState (Px DESC,SIDE ASC,Nemo ASC)
表Nemos:
CREATE CLUSTERED INDEX CIDX_Nemos ON Nemos (Nemo ASC)
检查以下查询
update t1 SET
MPV = pxV
,SaleContracts =SC
,MPC = pxC
,BuyContracts =BC
FROM
Nemos t1
JOIN
(
Select TOP 1 sum (Qty) as SC, px as pxV, @Nemo AS Nemo
from marketState
where Nemo = @Nemo and side=2
group by Px
ORDER BY px DESC
) srcA
ON srcA.Nemo=t1.Nemo
JOIN
(
Select TOP 1 sum (Qty) as BC, Px as pxC, @Nemo AS Nemo
from marketState
where Nemo = @Nemo and side=1
group by Px
order by px desc
) srcB
ON srcA.Nemo = srcB.Nemo
修改:1 强> 因为OP询问是否可以在单个读取和单个更新中执行此查询。但我不认为与上述相比,性能会有很大差异。
上面提到的相同索引也适用于此查询。
update t1 SET
MPV = q2.MPV
,SaleContracts =q2.SaleContracts
,MPC = q2.MPC
,BuyContracts =q2.BuyContracts
FROM
Nemos t1
JOIN
(
SELECT
SUM(CASE WHEN q1.side = 2 THEN q1.px END) AS MPV
,SUM(CASE WHEN q1.side=2 THEN q1.qty END) AS SaleContracts
,SUM(CASE WHEN q1.side=1 THEN px END) AS MPC
,SUM(CASE WHEN q1.side=1 THEN qty END) AS BuyContracts
,@Nemo AS Nemo
FROM
(
SELECT sum (Qty) as Qty,px,Side
,ROW_NUMBER() OVER (PARTITION BY side ORDER BY Px Desc) AS RowID
from marketState
where Nemo = @Nemo AND side IN (1,2)
group by Px,Side
)q1
WHERE q1.RowID=1
)q2
ON t1.nemo=q2.Nemo
答案 1 :(得分:-1)
如果目标是只读取一次MarketState表,那么我将在一个查询中计算您的两个值,并将这些结果放在临时表中。然后,您可以使用临时表在Nemos表上执行UPDATE。
像这样......
SELECT Px, Side, SUM(Qty) SC
INTO #Results
FROM marketState
WHERE Nemo = @Nemo
GROUP BY Px, Side
UPDATE Nemos
SET MPV = px,
SaleContracts = SC
FROM (SELECT TOP 1 (Qty) SC,
Px
FROM #Results
WHERE side = 2
ORDER BY Qty) src
WHERE Nemo = @Nemo
UPDATE Nemos
SET MPC = px,
SaleContracts = SC
FROM (SELECT TOP 1 (Qty) SC,
Px
FROM #Results
WHERE side = 1
ORDER BY Qty) src
WHERE Nemo = @Nemo