我正在尝试对包含大约700K记录的表进行批量更新。我需要使用上一条记录的有效结束日期更新有效开始日期。使用子查询时,我在更新语句上遇到问题。即使使用日期过滤器也需要一个多小时才能运行(2016年7月1日至2016年6月15日,大约2k记录)。我在一个简单的更新语句,插入和循环中尝试了它。使用ROWID而不是account_dim_key(表上的PK)的解释计划更加优化,但是,我得到一个错误,即子查询返回多行。我不确定为什么ROWID会发生这种情况。
ID是表上的自然键,account_dim_key是PK且唯一。两者都被编入索引。表是2型SCD。
使用ROWID更新语句返回错误单行子查询返回多行但具有最佳解释计划
UPDATE DEXWHS.D_ACCOUNT_VEEVA
SET effective_end_dt =
(SELECT prev_dt
FROM (SELECT LAG (
effective_end_dt,
1,
effective_start_dt)
OVER (PARTITION BY account_dim_key
ORDER BY effective_start_dt)
AS prev_dt,
ROWID AS rid
FROM dexwhs.d_account_veeva ac2) a
WHERE a.rid = ROWID)
使用非最佳解释计划的acocunt_dim_key更新语句
UPDATE DEXWHS.D_ACCOUNT_VEEVA
SET effective_end_dt =
(SELECT prev_dt
FROM (SELECT LAG (
effective_end_dt,
1,
effective_start_dt)
OVER (PARTITION BY id
ORDER BY effective_start_dt, account_dim_key)
AS prev_dt,
account_dim_key AS rid
FROM dexwhs.d_account_veeva ac2) a
WHERE a.rid = account_dim_key)
使用循环更新
CREATE OR REPLACE PROCEDURE PREV_UPDT
IS
CURSOR c1
IS
SELECT account_dim_key,
id,
active_flag,
effective_end_dt,
effective_start_dt,
created_date,
last_modified_date,
(SELECT prev_dt
FROM (SELECT LAG (
effective_end_dt,
1,
effective_start_dt)
OVER (
PARTITION BY id
ORDER BY effective_start_dt, account_dim_key)
AS prev_dt,
account_dim_key AS rid
FROM dexwhs.d_account_veeva ac2) a
WHERE a.rid = src.account_dim_key)
FROM dexwhs.d_account_veeva src
ORDER BY id, effective_start_dt, account_dim_key;
r1 c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO r1;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('id=' || r1.id);
UPDATE dexwhs.D_ACCOUNT_VEEVA trgt
SET trgt.effective_start_dt = r1.prev_date,
trgt.audit_last_update_dt = SYSDATE,
WHERE trgt.account_dim_key = r1.account_dim_key;
DBMS_OUTPUT.PUT_LINE ('r1.id_found');
END LOOP;
CLOSE c1;
END
答案 0 :(得分:0)
如果var data1 = [
{month: 'Jan', A: 20, B: 5, C: 10},
{month: 'Feb', A: 30, B: 10, C: 20}
];
var data2 = [
{month: 'Mar', A: 10, B: 55, C: 100},
{month: 'Apr', A: 10, B: 70, C: 2}
];
var xData = ["A", "B", "C"];
var margin = {top: 20, right: 50, bottom: 30, left: 50},
width = 400 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.35);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function draw(data) {
var dataIntermediate = xData.map(function (c) {
return data.map(function (d) {
return {x: d.month, y: d[c]};
});
});
var dataStackLayout = d3.layout.stack()(dataIntermediate);
x.domain(dataStackLayout[0].map(function (d) {
return d.x;
}));
y.domain([0,
d3.max(dataStackLayout[dataStackLayout.length - 1],
function (d) { return d.y0 + d.y;})
])
.nice();
var layer = svg.selectAll(".stack")
.data(dataStackLayout);
layer.exit().remove(); // has no effect
layer.enter().append("g")
.attr("class", "stack")
.style("fill", function (d, i) {
return color(i);
});
var rect = layer.selectAll("rect")
.data(function (d) {
return d;
});
rect.exit().remove(); // has no effect
rect.enter().append("rect")
.attr("x", function (d) {
return x(d.x);
})
.attr("y", function (d) {
return y(d.y + d.y0);
})
.attr("height", function (d) {
return y(d.y0) - y(d.y + d.y0);
})
.attr("width", x.rangeBand());
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.call(yAxis);
}
function updateData() {
draw(data2);
}
d3.select('#update')
.on("click", updateData);
draw(data1);
是主键,请尝试account_dim_key
MERGE
查询必须花一些时间,因为它正在更新整个表格。
也许您可以使用MERGE INTO dexwhs.d_account_veeva a
USING (
SELECT account_dim_key,
LAG ( effective_end_dt, 1, effective_start_dt)
OVER (PARTITION BY account_dim_key
ORDER BY effective_start_dt)
AS prev_dt
FROM dexwhs.d_account_veeva
) b
ON (a.account_dim_key = b.account_dim_key )
WHEN MATCHED THEN UPDATE SET a.effective_end_dt = b.prev_dt
列上的复合索引加快LAG ... (PARTITION BY account_dim_key ORDER BY effective_start_dt)
部分。
(account_dim_key, effective_start_dt)
但是Oracle可以忽略这个索引并且更喜欢全表扫描,因为子查询是针对整个表的。