【问题标题】:Bad performance on deleting referenced database rows with Linq To SQL使用 Linq To SQL 删除引用的数据库行时性能不佳
【发布时间】:2010-11-07 13:14:17
【问题描述】:

我在使用 MSSQL DB 的应用程序中遇到了性能问题。我有一个包含以下表格的数据库架构:

  • 工作(主键:Job ID),
  • Jobitem(主键:Jobitem ID,外键:Job ID),
  • Job2Property(外键:Job ID Property ID),
  • Jobitem2Property(外键:Jobitem ID Property ID),
  • 属性(主键:Property ID)。

现在,当我想删除作业时,我首先必须删除它的 Jobitems,然后是 Job2Property 引用,最后我可以删除属性和作业本身。对于 Jobitem,我还需要先删除 Jobitem2Property 引用,然后是其属性和 Jobitem 本身。

这是删除作业的方法:

public void Delete(List<Job> jobsToDelete)
{
    var jobitemsToDelete = new List<Jobitem>();

    // Gather references to jobitems to delete
    foreach (Job job in jobsToDelete) {
        List<Jobitem> jobitems =
            (from ji in job.Jobitems.Values
             select ji).ToList();

        jobitemsToDelete.AddRange(jobitems);
    }

    // first the related jobitems and the properties have to be deleted
    PropertyManager.Instance.Delete(jobsToDelete);        
    Delete(jobitemsToDelete);

    dbc.Job.DeleteAllOnSubmit(jobsToDelete);
    dbc.SubmitChanges();

    // Remove Job from dictionary to avoid using Refresh()
    foreach (Job job in jobsToDelete) {
        Jobs.Remove(job.Id);
    }
}

以下方法删除jobitems:

public void Delete(List<Jobitem> jobitemsToDelete)
{
    PropertyManager.Instance.Delete(jobitemsToDelete);

    dbc.Jobitem.DeleteAllOnSubmit(jobitemsToDelete);
    dbc.SubmitChanges();
}

最后是删除属性的方法:

public void Delete(List<Job> jobsToDelete)
{
    List<Property> propsToDelete = new List<Property>();

    foreach (Job job in jobsToDelete) {
        if (JobProperties.ContainsKey(job.Id))
            propsToDelete.AddRange(JobProperties[job.Id]);
    }

    List<Job2Property> j2pToDelete =
        (from p in propsToDelete
         select p.Job2Property.First()).ToList();

    dbc.Job2Property.DeleteAllOnSubmit(j2pToDelete);
    dbc.Property.DeleteAllOnSubmit(propsToDelete);
    dbc.SubmitChanges();
}

删除jobitem属性的方法看起来完全一样,只是它以List&lt;Jobitem&gt;作为参数。

现在删除的性能真的很差。对于单个作业,大约需要 3 秒。当我删除 10 行时,需要 13 到 14 秒。在我拥有 Property 和 XYZ2Property 表之前,它只需要不到一秒钟的时间。

如何优化这个速度? 使用 ProfileSharp 分析应用程序我得出的结论是,删除函数占用了应用程序总处理时间的大约 17%(即 9405781250 个时间单位),而在最后一种删除属性的方法似乎占用了大部分时间(它说 1475%,但这似乎是 ProfileSharp 的一个错误。相反,我猜它占用了这 17% 的大部分)。

Here's a picture of the profile.

我能做点什么吗?

【问题讨论】:

    标签: c# sql-server performance optimization linq-to-sql


    【解决方案1】:

    这是什么数据库?无论如何,我没有责任删除所有这些工作、工作项和工作属性以及不在代码中的内容,而是在数据库中。对于外键,可以指定级联删除,也就是说如果你删除了某个job,所有对应的jobitems和property也会被删除。它为您节省了大量代码,并且不易出错。查一下。在 SQL Server Management Studio 中,它位于外键关系编辑器下方。

    它也可能会更快,因为您不必执行选择查询来检索所有相应的作业项和属性。简而言之,您将获得更少的代码、更少的错误和更高的性能。

    【讨论】:

    • 我正在使用 MSSQL。所以级联删除是一个数据库设置,我不需要在我的代码中做任何事情,只需删除一个作业?
    • 是的,没错。查看firstsql.com/tutor6.htm 并阅读有关“参照完整性”的部分。
    • 或者自己尝试一下。我认为你有 Sql Server Management Studio 或类似的东西,所以设置一些带有关系的测试表,添加一些数据,设置级联删除约束,看看会发生什么! :-)
    • 太好了,速度超级快!此外,它更容易。总结一下:各方面都更好。谢谢=)
    猜你喜欢
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多