我有一个像这样生成的插入查询
INSERT INTO InvoiceDetail (LegacyId,InvoiceId,DetailTypeId,Fee,FeeTax,Investigatorid,SalespersonId,CreateDate,CreatedById,IsChargeBack,Expense,RepoAgentId,PayeeName,ExpensePaymentId,AdjustDetailId)
VALUES(1,1,2,1500.0000,0.0000,163,1002,'11/30/2001 12:00:00 AM',1116,0,550.0000,850,NULL,@ExpensePay1,NULL);
DECLARE @InvDetail1 INT; SET @InvDetail1 = (SELECT @@IDENTITY);
Run Code Online (Sandbox Code Playgroud)
仅为110K行生成此查询.
所有这些查询都需要30分钟才能执行
我检查了查询计划,最大的%节点是
群集索引以57%的查询成本插入,其中包含一个我不想发布的长xml.
表Spool,查询成本为38%
<RelOp AvgRowSize="35" EstimateCPU="5.01038E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Eager Spool" NodeId="80" Parallel="false" PhysicalOp="Table Spool" EstimatedTotalSubtreeCost="0.0466109">
<OutputList>
<ColumnReference Database="[SkipPro]" Schema="[dbo]" Table="[InvoiceDetail]" Column="InvoiceId" />
<ColumnReference Database="[SkipPro]" Schema="[dbo]" Table="[InvoiceDetail]" Column="InvestigatorId" />
<ColumnReference Column="Expr1054" />
<ColumnReference Column="Expr1055" />
</OutputList>
<Spool PrimaryNodeId="3" />
</RelOp>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是我能做些什么来提高这件事的速度?我已经运行了ALTER TABLE TABLENAME NOCHECK CONSTRAINTS ALL在查询之前然后在查询之后ALTER TABLE TABLENAME NOCHECK CONSTRAINTS ALL.
这并没有消除任何时间的任何东西.
知道我在使用SqlCommand对象发送查询的.NET应用程序中运行这些查询.
然后我尝试将sql命令输出到一个文件,然后使用sqlcmd执行它,但我没有得到任何关于它如何做的更新,所以我放弃了.
任何想法或提示或帮助?
更新:
好的,所以你们都非常乐于助人.在这种情况下,我希望我能够赞扬不止一个答案.
解决这个问题的解决方案是双重的.
首先:
1)我禁用/重新启用所有外键(比丢弃它们容易得多)
ALTER …Run Code Online (Sandbox Code Playgroud) 我有现有的代码,看起来类似于:
IEnumerable<SomeClass> GetStuff()
{
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn)
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
SomeClass someClass = f(reader); // create instance based on returned row
yield return someClass;
}
}
}
Run Code Online (Sandbox Code Playgroud)
看来我可以通过使用获益reader.ReadAsync().但是,如果我只修改一行:
while (await reader.ReadAsync())
Run Code Online (Sandbox Code Playgroud)
编译器通知我await只能在标async有的方法中使用,并建议我修改方法签名为:
async Task<IEnumerable<SomeClass>> GetStuff()
Run Code Online (Sandbox Code Playgroud)
但是,这样做会导致GetStuff()无法使用,因为:
body
GetStuff()不能是迭代器块,因为Task<IEnumerable<SomeClass>>它不是迭代器接口类型.
我确信我错过了异步编程模型的关键概念.
问题:
ReadAsync()在我的迭代器中使用吗?怎么样?TPL Dataflow提供TransformBlock转换输入,例如:
var tb = new TransformBlock<int, int>(i => i * 2);
Run Code Online (Sandbox Code Playgroud)
是否有可能不输出一些输入,例如,如果输入未通过某些验证测试?
var tb = new TransformBlock<InputType, OutputType>(i =>
{
if (!ValidateInput(i))
{
// Do something to not output anything for this input
}
// Normal output
}
Run Code Online (Sandbox Code Playgroud)
如果那是不可能的,那么实现这一目标的最佳模式是什么?
像下面这样的东西?
BufferBlock<OutputType> output = new BufferBlock<OutputType>();
var ab = new ActionBlock<InputType>(i =>
{
if (ValidateInput(i))
{
output.Post(MyTransform(i));
}
}
Run Code Online (Sandbox Code Playgroud) 我发现编辑可变长度项目列表的最佳建议是在2008年为ASP.Net MVC 2编写的.
http://blog.stevensanderson.com/2008/12/22/editing-a-variable-length-list-of-items-in-aspnet-mvc/
这种方法仍然是ASP.Net MVC 4的最佳方法,还是有更新的解决方案既标准化又更优雅?
实体框架4备受期待的功能之一是能够以持久性无知方式使用POCO(普通旧CLR对象)(即他们不"知道"它们与实体框架相对于其他机制持久化).
我试图解决为什么必须执行关联修正并在我的"普通"业务对象中使用FixupCollection.这个要求似乎意味着业务对象毕竟不能完全忽略持久性机制(事实上,"fixup"这个词听起来像需要修复/改变以适应所选择的持久性机制).
具体来说,我指的是由ADO.NET POCO实体生成器生成的Association Fixup区域,例如:
#region Association Fixup
private void FixupImportFile(ImportFile previousValue)
{
if (previousValue != null && previousValue.Participants.Contains(this))
{
previousValue.Participants.Remove(this);
}
if (ImportFile != null)
{
if (!ImportFile.Participants.Contains(this))
{
ImportFile.Participants.Add(this);
}
if (ImportFileId != ImportFile.Id)
{
ImportFileId = ImportFile.Id;
}
}
}
#endregion
Run Code Online (Sandbox Code Playgroud)
以及FixupCollection的使用.其他常见的持久性无知ORM没有类似的限制.
这是由于EF的基本设计决定吗?即使在EF的后期版本中,是否存在某种程度的非无知?是否有一种聪明的方法可以隐藏POCO开发人员的持久性依赖性?
这在实践中如何实现,端到端?例如,我理解最近才为ObservableCollection添加了支持(Silverlight和WPF需要它).其他软件层是否存在EF兼容POCO对象的设计要求?
我首先将int32数字转换为char [4]数组,然后通过(int*)将数组转换回int32,但数字与之前的数字不同:
unsigned int num = 2130706432;
unsigned int x;
unsigned char a[4];
a[0] = (num>>24) & 0xFF;
a[1] = (num>>16) & 0xFF;
a[2] = (num>>8) & 0xFF;
a[3] = num & 0xFF;
x = *(int *)a;
printf("%d\n", x);
Run Code Online (Sandbox Code Playgroud)
输出是127.如果我设置num = 127,输出是2130706432.有没有人有想法?
我在我的一个项目中使用自定义堆实现.它由两个主要部分组成:
修复了大小块堆.即只分配特定大小的块的堆.它分配更大的内存块(虚拟内存页或来自另一个堆),然后将它们分成原子分配单元.
它快速执行分配/释放(在O(1)中)并且没有内存使用开销,没有考虑外部堆强加的事情.
全球通用堆.它由上面(固定尺寸)堆的桶组成.WRT它选择适当存储桶的请求分配大小,并通过它执行分配.
由于整个应用程序(大量)是多线程的 - 全局堆在其操作期间锁定适当的存储桶.
注意:与传统堆相比,此堆不仅要求分配大小,还要求释放分配大小.这允许在没有搜索或额外的内存开销的情况下识别适当的桶(例如在分配的块之前保存块大小).虽然不太方便,但在我的情况下这是好的.此外,由于"桶配置"在编译时是已知的(通过C++模板voodoo实现) - 在编译时确定适当的桶.
到目前为止,一切看起来(并且有效).
最近我研究了一种能够大量执行堆操作的算法,并且自然会受到堆性能的影响.分析显示其锁定会对其性能产生很大影响.也就是说,堆本身工作得非常快(典型的分配只涉及一些内存解除引用指令),但由于整个应用程序是多线程的 - 适当的存储桶受关键部分的保护,它依赖于互锁指令,这些指令很多重.
我通过给这个算法提供了自己的专用堆来解决这个问题,这个堆不受关键部分的保护.但这在代码级别强加了几个问题/限制.例如,需要在堆栈深处传递上下文信息,无论堆可能在哪里.也可以使用TLS来避免这种情况,但这可能会导致我在特定情况下重新进入时出现一些问题.
这让我想知道:是否有一种已知的技术来优化堆(但不限于)单线程使用?
编辑:
特别感谢@Voo建议查看google的tcmalloc.
它似乎与我做的更多或更少(至少对于小对象)的工作类似.但此外,他们通过维护每线程缓存来解决我所遇到的确切问题.
我也想过这个方向,但我想保持每线程堆.然后释放从属于另一个线程的堆分配的内存块有点棘手:应该将其插入到一个锁定队列中,并且应该通知其他线程,并异步释放挂起的分配.异步释放可能会导致问题:如果该线程由于某种原因而忙(例如执行积极的计算) - 实际上不会发生内存释放.此外,在多线程场景中,释放的成本要高得多.
OTOH使用缓存的想法似乎更简单,更有效.我会尝试解决它.
非常感谢.
PS:
事实上谷歌的tcmalloc很棒.我相信它的实现与我所做的非常相似(至少是固定大小的部分).
但是,要迂腐,有一件事我的堆优越.根据文档,tcmalloc大约1%的开销(渐近),而我的开销是0.0061%.确切地说是4/64K.
:)
简单模态失败,jQuery 1.8.0和IE9出错:
SCRIPT438:对象不支持属性或方法'removeExpression'
以下小提琴演示(记得用IE9运行)
http://jsfiddle.net/ericjohannsen/ZVEWa/1/
将jQuery切换到1.7.2会导致错误消失.
有办法解决这个问题吗?
可能相关(OP说问题是jQuery 1.7.1和iframe)
SimpleModal在IE 9中不起作用(在iframe内部)
不相关(jQuery 1.5问题)
背景
我有一个应用程序接收定期数据转储(XML文件)并使用Entity Framework 5(代码优先)将它们导入现有数据库.导入通过EF5而不是BULK INSERT或BCP进行,因为必须应用已存在于实体中的业务规则.
处理似乎是应用程序本身的CPU绑定(极快,启用了写缓存的磁盘IO子系统在整个过程中显示几乎为零的磁盘等待时间,而SQL Server显示的CPU时间不超过8%-10%).
为了提高效率,我使用TPL Dataflow构建了一个管道,其组件包括:
Read & Parse XML file
|
V
Create entities from XML Node
|
V
Batch entities (BatchBlock, currently n=200)
|
V
Create new DbContext / insert batched entities / ctx.SaveChanges()
Run Code Online (Sandbox Code Playgroud)
通过这样做,我看到性能大幅提升,但不能使CPU高于60%.
分析
怀疑某种资源争用,我使用VS2012 Profiler的资源争用数据(并发)模式运行该过程.
分析器显示52%的争用标记为句柄2的资源.钻进,我看到创建Handle 2最多争用的方法是
System.Data.Entity.Internal.InternalContext.SaveChanges()
Run Code Online (Sandbox Code Playgroud)
第二名,与SaveChanges()的争论大约是40%
System.Data.Entity.DbSet`1.Add(!0)
Run Code Online (Sandbox Code Playgroud)
问题
UPDATE
对于有问题的运行,调用SaveChanges的任务的最大并行度设置为12(我尝试了各种值,包括先前运行中的Unbounded).
更新2
微软的EF团队提供了反馈意见.请参阅我的答案以获取摘要.
parallel-processing profiling entity-framework task-parallel-library tpl-dataflow
c# ×3
c ×2
tpl-dataflow ×2
.net ×1
ado.net ×1
asp.net-mvc ×1
async-await ×1
bulkinsert ×1
c++ ×1
debugging ×1
generator ×1
heap ×1
insert ×1
jquery ×1
poco ×1
profiling ×1
simplemodal ×1
sql-server ×1
t4 ×1
yield-return ×1