我有以下查询的问题
UPDATE P
set P.price = (select top 1 PV.price
from @port_values PV
where PV.pv_id < P.pv_id
and PV.price is not NULL
and PV.id = P.id
order by PV.pv_id desc)
FROM @port_values P
WHERE P.price is NULL
它正在做的是回顾历史,找到任何先前的价格值并应用于有NULL价格的地方。 pv_id
按日期顺序排列并编入索引。它以前按日期排序,但性能没有变化。
它正在以合理的性能工作,但是数据库变大了,这行代码实际上挂起了查询。对于较小的数据集,可以,但在@port_values有大约400k行的情况下。它显然是在进行迭代表扫描而根本没有效率。我已经尝试将索引放在具有任何性能的列上。
构建像这样的查询最有效的方法是什么?
由于您的环境不可用,我们无法提供准确的解决方案。但请尝试下面的内容,如果对性能有任何影响,请告诉我
方法1:
UPDATE P SET P.price = PV.price
FROM @port_values P
INNER JOIN
(
SELECT id, price FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY PV.id ORDER BY PV.pv_id ASC) AS SNO
,PV.id
,PV.price
FROM @port_values PV
WHERE PV.price is not NULL
)AS A
WHERE SNO= 1
)PV ON P.id = PV.ID
WHERE P.price is NULL
方法2:
CREATE TABLE #TAB (ID INT PRIMARY KEY, price DECIMAL(18,2))
INSERT INTO #TAB
SELECT id, price FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY PV.id ORDER BY PV.pv_id ASC) AS SNO
,PV.id
,PV.price
FROM @port_values PV
WHERE PV.price is not NULL
)AS A
WHERE SNO= 1
UPDATE P SET P.price = PV.price
FROM @port_values P
INNER JOIN #TAB PV ON P.id = PV.ID
WHERE P.price is NULL
尝试这个非标准的sql表现更好,
UPDATE P
set P.price = s.price
FROM @port_values P
Outer apply(
select top 1 PV.price
from @port_values PV
where PV.pv_id < P.pv_id
and PV.price is not NULL
and PV.id = P.id
and P.price is null
order by PV.pv_id desc ) s
WHERE P.price is NULL
使用可更新的CTE:
with toupdate as (
select p.*,
lag(p.price) over (partition by p.pv_id order by p.id) as prev_price
from @port_values p
where p.price is not null
)
update toupdate
set price = prev_price;
对于性能,您需要(pv_id, id, price)
上的索引。在最新版本的SQL Server中,这些表变量是允许的。在旧版本中,使用临时表以便添加索引。