gpt4 book ai didi

c# - 计算安装基数的最有效方法是什么?

转载 作者:行者123 更新时间:2023-11-30 17:58:41 25 4
gpt4 key购买 nike

我需要计算多年来在不同国家/地区具有不同“环境”的不同放置/出货量的装置的安装基数,给定一组分配给每个装置的特定“报废率”。放置、曲线定义和曲线分配存储在不同的数据库表中(下面有 DDL 和示例数据,也在 SQLFiddle.com 上)。安装基数的计算公式如下:

enter image description here其中 1990 年是我们获得安置数据的第一年。

问题:

使用 3 到 1600 万行单位/国家/环境/年份放置组合的数据集进行这些计算比 30 秒到 1 分钟的目标加载/计算时间要长得多。

SQL Server 方法

PIVOT ed 以便每一年都成为自己的专栏,我从 100,000 到 400,000 行返回的原始数据行(展示位置 + 费率)中的任何地方,这大约需要 8-15 秒。但是,如果我通过下面包含的 SQL 语句手动计算,则至少需要 10 分钟。

我们还尝试了一种 SQL 触发器解决方案,该解决方案在每次修改展示位置或费率时更新已安装的基础,但这使得数据库更新在批量更新时异常缓慢,而且也不可靠。我想如果这真的是最好的选择,这可能值得更多的调查。

Excel-VSTO 方法(到目前为止,最快的方法):

此数据最终会出现在 C# VSTO 支持的 Excel 工作簿中,其中数据是通过一系列 VLOOKUPs 计算得出的,但是当在 6 年内加载 150,000 个展示位置时,大约 20 VLOOKUPs每个单元格(约 2000 万 VLOOKUPs ),Excel 崩溃。当 VLOOKUPs以较小的批处理完成并将公式转换为值,它不会崩溃,但计算时间仍然超过一分钟。

问题:

是否有一些数学或编程结构可以帮助我通过 C# 或 SQL 比以往更有效地计算这些数据?蛮力迭代也太慢了,所以这也不是一个选择。

DECLARE @Placements TABLE 
(
UnitId int not null,
Environment varchar(50) not null,
Country varchar(100) not null,
YearColumn smallint not null,
Placement decimal(18,2) not null,
PRIMARY KEY (UnitId, Environment, Country, YearColumn)
)


DECLARE @CurveAssignments TABLE
(
UnitId int not null,
Environment varchar(50) not null,
Country varchar(100) not null,
YearColumn smallint not null,
RateId int not null,
PRIMARY KEY (UnitId, Environment, Country, YearColumn)
)

DECLARE @CurveDefinitions TABLE
(
RateId int not null,
YearOffset int not null,
Rate decimal(18,2) not null,
PRIMARY KEY (RateId, YearOffset)
)

INSERT INTO
@Placements
(
UnitId,
Country,
YearColumn,
Environment,
Placement
)
VALUES
(
1,
'United States',
1991,
'Windows',
100
),
(
1,
'United States',
1990,
'Windows',
100
)

INSERT INTO
@CurveAssignments
(
UnitId,
Country,
YearColumn,
Environment,
RateId
)
VALUES
(
1,
'United States',
1991,
'Windows',
1
)

INSERT INTO
@CurveDefinitions
(
RateId,
YearOffset,
Rate
)
VALUES
(
1,
0,
1
),
(
1,
1,
0.5
)

SELECT
P.UnitId,
P.Country,
P.YearColumn,
P.Placement *
(
SELECT
Rate
FROM
@CurveDefinitions CD
INNER JOIN @CurveAssignments CA ON
CD.RateId = CA.RateId
WHERE
CA.UnitId = P.UnitId
AND CA.Environment = P.Environment
AND CA.Country = P.Country
AND CA.YearColumn = P.YearColumn - 0
AND CD.YearOffset = 0
)
+
(
SELECT
Placement
FROM
@Placements PP
WHERE
PP.UnitId = P.UnitId
AND PP.Environment = P.Environment
AND PP.Country = P.Country
AND PP.YearColumn = P.YearColumn - 1
)
*
(
SELECT
Rate
FROM
@CurveDefinitions CD
INNER JOIN @CurveAssignments CA ON
CD.RateId = CA.RateId
WHERE
CA.UnitId = P.UnitId
AND CA.Environment = P.Environment
AND CA.Country = P.Country
AND CA.YearColumn = P.YearColumn
AND CD.YearOffset = 1
) [Installed Base - 1993]
FROM
@Placements P
WHERE
P.UnitId = 1
AND P.Country = 'United States'
AND P.YearColumn = 1991
AND P.Environment = 'Windows'

最佳答案

作为回应,声明如下:

We've also tried an SQL trigger solution that updated the installed base each time a placement or rate was modified, but that made database updates unreasonably slow on batch updates, and was also unreliable. I suppose this could merit more investigation if this were really the best option.

你听说过SQL Service Broker吗? ?它做得很好的一件事是允许您将数据排队以进行异步处理。如果触发器本身太慢,您可以使用触发器将记录排队以进行异步处理。

关于c# - 计算安装基数的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12013191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com