- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 LinqToSQL 处理来自 SQL Server 的数据,以将其转储到 iSeries 服务器以进行进一步处理。 More details on that here .
我的问题是处理这 350 行数据大约需要 1.25 分钟。我仍在尝试破译 SQL Server Profiler 的结果,但是正在运行大量查询。以下是我正在做的事情的更多细节:
using (CarteGraphDataDataContext db = new CarteGraphDataDataContext())
{
var vehicles = from a in db.EquipmentMainGenerals
join b in db.EquipmentMainConditions on a.wdEquipmentMainGeneralOID equals b.wdEquipmentMainGeneralOID
where b.Retired == null
orderby a.VehicleId
select a;
et = new EquipmentTable[vehicles.Count()];
foreach (var vehicle in vehicles)
{
// Move data to the array
// Rates
GetVehcileRates(vehicle.wdEquipmentMainGeneralOID);
// Build the costs accumulators
GetPartsAndOilCosts(vehicle.VehicleId);
GetAccidentAndOutRepairCosts(vehicle.wdEquipmentMainGeneralOID);
// Last Month's Accumulators
et[i].lastMonthActualGasOil = GetFuel(vehicle.wdEquipmentMainGeneralOID) + Convert.ToDecimal(oilCost);
et[i].lastMonthActualParts = Convert.ToDecimal(partsCost);
et[i].lastMonthActualLabor = GetLabor(vehicle.VehicleId);
et[i].lastMonthActualOutRepairs = Convert.ToDecimal(outRepairCosts);
et[i].lastMonthActualAccidentCosts = Convert.ToDecimal(accidentCosts);
// Move more data to the array
i++;
}
}
Get 方法看起来都类似于:
private void GetPartsAndOilCosts(string vehicleKey)
{
oilCost = 0;
partsCost = 0;
using (CarteGraphDataDataContext db = new CarteGraphDataDataContext())
{
try
{
var costs = from a in db.WorkOrders
join b in db.MaterialLogs on a.WorkOrderId equals b.WorkOrder
join c in db.Materials on b.wdMaterialMainGeneralOID equals c.wdMaterialMainGeneralOID
where (monthBeginDate.Date <= a.WOClosedDate && a.WOClosedDate <= monthEndDate.Date) && a.EquipmentID == vehicleKey
group b by c.Fuel into d
select new
{
isFuel = d.Key,
totalCost = d.Sum(b => b.Cost)
};
foreach (var cost in costs)
{
if (cost.isFuel == 1)
{
oilCost = (double)cost.totalCost * (1 + OVERHEAD_RATE);
}
else
{
partsCost = (double)cost.totalCost * (1 + OVERHEAD_RATE);
}
}
}
catch (InvalidOperationException e)
{
oilCost = 0;
partsCost = 0;
}
}
return;
}
我的想法是减少对数据库的查询数量以加快处理速度。如果 LINQ 对每条记录执行 SELECT,也许我需要先将每条记录加载到内存中。
总的来说,我仍然认为自己是 C# 和 OOP 的初学者(我主要在 iSeries 上进行 RPG 编程)。所以我猜我在做一些愚蠢的事情。你能帮我解决我的愚蠢问题(至少在这个问题上)吗?
更新:我想我会回来向您更新我的发现。看起来数据库设计得很糟糕。无论 LINQ 在后台生成什么,它都是非常低效的代码。我并不是说 LINQ 不好,它只是对这个数据库不好。我转换为快速组合的 .XSD 设置,处理时间从 1.25 分钟减少到 15 秒。一旦我进行了适当的重新设计,我只能猜测我会再缩短几秒钟。谢谢大家的评论。改天我会在更好的数据库上再次尝试 LINQ。
最佳答案
我在您的代码中发现了几件事:
select
中使用匿名类型以提高性能。 . LINQ to SQL 将对此进行分析并从数据库中检索较少的数据。这样的选择可能如下所示:select new { a.VehicleId, a.Name }
GetPartsAndOilCosts
中的查询可以通过计算 cost.totalCost * (1 + OVERHEAD_RATE)
来优化在 LINQ 查询中。这样查询就可以完全在数据库中执行,这应该会更快。Count()
在 var vehicles
上查询,但您仅将其用于确定数组的大小。虽然 LINQ to SQL 会非常高效 SELECT count(*)
查询它,它需要额外的往返数据库。除此之外(取决于您的隔离级别)您开始迭代查询的时间可以添加一个项目。在那种情况下,您的数组太小并且 ArrayIndexOutOfBoundsException
将被抛出。您可以简单地使用 .ToArray()
在查询或创建 List<EquipmentTable>
并调用.ToArray()
在那上面。这通常足够快,尤其是当您在此集合中只有 380 项时,这肯定比额外往返数据库(计数)要快。对第 1 点的一些额外解释。你在这里所做的有点像这样:
var query = from x in A select something;
foreach (var row in query)
{
var query2 = from y in data where y.Value = row.Value select something;
foreach (var row2 in query2)
{
// do some computation.
}
}
您应该尝试完成的是删除 query2
子查询,因为它在顶级查询的每一行上执行。所以你最终可能会得到这样的结果:
var query =
from x in A
from y in B
where x.Value == y.Value
select something;
foreach (var row in query)
{
}
当然,这个例子很简单,在现实生活中它会变得相当复杂(正如您已经注意到的那样)。在您的情况下,还因为您有多个“子查询”。您可能需要一些时间才能做到这一点,尤其是在您缺乏 LINQ to SQL 知识的情况下(正如您自己所说)。
如果您无法弄清楚,您可以随时在 Stackoverflow 上再次提问,但请记住将您的问题剥离到尽可能小的部分,因为阅读别人的烂摊子没有乐趣(我们没有得到报酬为了这) :-)祝你好运。
关于c# - 什么更快?结构数组或数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2418571/
我有一个带有嵌套数据的 angular 数据表,我正在尝试在行点击函数上创建另一个数据表。父数据表的 rowCallBack 函数。 这是我的外部数据表 html; 这是我生成数据表的方
我有一个字母数字列,其中包含诸如“1、2、2”之类的字符串。 当我在搜索中输入“1, 2, 2”时,它似乎返回带有“1,”和“2,”的所有单元格。 我该怎么做才能使搜索仅返回“1、2、2”? 使用数据
我有一个获取其数据服务器端的表,使用自定义服务器端初始化参数,这些参数因生成的报告而异。表格生成后,用户可以打开一个弹出窗口,他们可以在其中添加多个附加过滤器以进行搜索。我需要能够使用与原始表相同的初
在 datatables我希望能够隐藏所有列,但似乎无法正确使用语法。 这来自下面的代码和上面的链接,创建了一个显示所有列的按钮。有没有办法写这个以便我可以隐藏所有列? {
我正在使用 DataTable 创建一个交互式表。我有 9 列,其中 5 列是值。我想根据它们的具体情况更改每个单元格的背景颜色。 我已经开始尝试首先更改整行颜色,因为这似乎是一项更容易的任务。但是我
我有一个简单的例子来说明我的问题。我正在使用数据表 1.9。当数据表位于另一个 html 表内时,水平滚动时列标题不会移动。当它不在 html 表中时它工作正常。我的示例实际上取自他们的水平滚动示例,
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
这是添加按钮以将数据导出到 csv、pdf、excel 的数据表示例...... fiddle here https://datatables.net/extensions/buttons/examp
是否有任何方法可以更改 angularjs 数据表中的按钮样式(colvis、copy、print、excel)。 vm.dtOptions = DTOptionsBuilder.newOptions
我试图弄清楚如何加入 2 个数据表并更新第一个但应用了过滤器。 DT DT2 b c 1: 1 10 2: 2 10 3: 3 10 4: 4 10 5: 5 10 6: 6 10 7: 7 10
我有一个数据表,其中包含许多包含值的列。我还有另一列,它定义了我需要选择哪些列的值。我很难找到一种方法来做到这一点。 这是一个简单的例子。 > d d value.1 value.2 name
我正在使用 data.table 包。我有一个数据表,表示用户在网站上的操作。假设每个用户都可以访问一个网站,并对其执行多项操作。我的原始数据表是 Action (每一行都是一个 Action ),我
我想知道每个变量在每个组中变化了多少次,然后将结果添加到所有组中。 我是这样找到的: mi[,lapply(.SD, function(x) sum(x != shift(x), na.rm=T)
有人可以向我解释一下如何向页眉或页脚添加按钮吗?Datatables 的开发者 Alan 说你必须离开网络服务器才能使用 Table Tools 来使用按钮。但我在独立计算机上离线运行 Datatab
我希望按 id 和按顺序(时间)计算不同的东西。 例如,与: dt = data.table( id=c(1,1,1,2,2,2,3,3,3), hour=c(1,5,5,6,7,8,23,23,23
我正在尝试在 JIRA 小工具中使用数据表,但在我的表准备就绪后,没有可用的分页按钮。我有一个表,我正在以最简单的方式使用数据表:$("#mytableid").dataTable(); 浏览页面元素
我有 responsive 表单中的数据表。 数据表生成 child rows在小型设备上。在这一行中,我有一些输入控件。这会导致两个问题。 第一个问题:**隐藏子行中的值不会进入表单数据。** 第二
我在使用 JQuery DataTable 捕获 keydown 事件时遇到问题。我的目标是允许用户使用箭头键导航表的行。因此,当用户按下箭头键时,我想捕获 keydown 事件并移动表的选定行(这是
是否有任何方法可以以编程方式更改显示的行数,而无需从下拉列表中手动选择? 我已经知道如何更改默认行数。当表首次加载时,我希望它加载所有行,然后“刷新”表以可能仅显示前 10 行。但我想以编程方式刷新表
我有一个数据表,我应该对其进行更改,例如我想更改内容的状态,但该内容位于表的第三页。当我更改它时,数据表会自行刷新到第一页。我想做的是保留选定的页码并在刷新后回调它。这可能吗? 顺便说一句,我正在使用
我是一名优秀的程序员,十分优秀!