【问题标题】:Change of design of queries to improve performance更改查询设计以提高性能
【发布时间】:2011-05-09 02:54:52
【问题描述】:

这更像是一个设计问题,但也与 SQL 优化有关。

我的项目必须将大量记录导入数据库(超过 10 万条记录)。同时,该项目具有检查每条记录的逻辑,以确保它符合可配置的标准。然后它会将记录标记为无警告或在数据库中有警告。插入和警告检查在一个导入过程中完成。

对于每个条件,它都必须查询数据库。查询需要连接另外两个表,有时会在条件内添加额外的嵌套查询,例如

select * from TableA a 
  join TableB on ... 
  join TableC on ... 
where
  (select count(*) from TableA 
where TableA.Field = Bla) > 100

尽管查询花费的时间并不明显,但查询整个记录集需要相当长的时间,在服务器上可能需要 4 到 5 个小时。特别是如果有很多条件,最后项目将停止运行导入和回滚。

我尝试将“SELECT * FROM”更改为“SELECT TableA.ID FROM”,但似乎完全没有效果。有没有更好的设计来提高这个过程的性能?

【问题讨论】:

    标签: java sql-server performance


    【解决方案1】:

    如何创建一个临时表(或多个)来存储子查询的聚合结果,然后用覆盖索引对该/那些进行索引。

    根据您上面的代码,我们将在 TableA.Field1 上创建一个临时表分组并包含一个计数,然后在 Field1 上建立索引 theCount。在 SQL Server 上,最快的方法是:

    select * from TableA a 
      join TableB on ... 
      join TableC on ... 
      join (select Field1 from #temp1 where theCount > 100) t on...
    

    之所以有效,是因为我们重复了相同的技巧。

    首先,我们预先聚合到临时表中,这是一个简单的操作,很容易被 SQL Server 优化。所以我们采取了一部分问题并以可优化的方式解决。

    然后我们通过加入子查询来重复这个技巧,将过滤器放在子查询中,以便连接充当过滤器。

    【讨论】:

    • 我应该在哪里制作临时表? “(select count(*) from TableA where TableA.Field1 = Bla and TableA.Field2=Blaa and...)”查询也来自数据库,所以我必须先想办法将其转换为临时表.
    • 我假设您正在分阶段执行此操作。首先,将 100k 行加载到“收件箱”表或临时表中。接下来,您将通过一个或多个步骤从该表中提取数据,以将数据传送到最终目的地。因此,临时表既可以在存储过程中创建,也可以在应用程序代码中创建。
    【解决方案2】:

    我建议您将您的记录批量处理(一次大约 500 个)并将其发送到可以进行计算的存储过程。

    在那里使用简单的语句而不是连接。这样也省钱。这个link 也可能有帮助。

    【讨论】:

      【解决方案3】:

      不错的选择是使用索引视图。 http://msdn.microsoft.com/en-us/library/dd171921(SQL.100).aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-08
        • 2012-10-19
        • 2013-08-03
        • 2021-08-26
        • 1970-01-01
        • 2014-11-14
        • 1970-01-01
        相关资源
        最近更新 更多