在SQL Server上批量查询需要几毫秒到2分钟

时间:2013-12-13 10:14:45

标签: sql-server batch-processing database-deadlocks

我有一个批处理,可以加载从大约一百个XLS工作簿中解析的配置数据,包含有关单元格位置,单元格类型,单元格含义等信息。

这是一个非常大的批处理,它涉及使用几个临时表,

由于它可以从现有配置开始,因此需要合并这两个配置,因此一些临时表在事务外填充,一些填充在事务中。

Oracle 10g 上,批处理执行没有任何问题。

SQLServer 2008 R2 上,我遇到了一些随机挂起的2-3个交易中INSERT个查询。这件事并不总是发生,或者它可能发生在一个查询(通常在几毫秒内执行),而不是发生在它之前发生的另一个查询上。

我最初想到了一个死锁,但是将查询超时提升到3分钟,它最终会在大约2分钟内执行。我再说一遍,这些查询有时会以几毫秒的速度执行。

我还指定所有查询都使用ROWLOCK选项完成。

使用分析器和活动监视器监视SQL Server我没有看到任何奇怪的内容 CPU没有挂起,有内存,磁盘读取大约为0,磁盘写入为0-200 kb / s不恒定。

没有其他人在使用此数据库架构。

我真的无法解决这个问题。

修改

这是令人费解的查询的 一个

INSERT INTO "LOAD"."META_CELLS_UOM" WITH (ROWLOCK) 
("UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID") 

  SELECT "UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID"
   FROM ( 
     SELECT "META_DOCUMENTS"."UDA_DOMAIN_ID", "META_DOCUMENTS"."META_DOC_ID", "META_SECTIONS"."META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_ROW" AS "META_CELL_UROW", "META_CELL_COL" AS "META_CELL_UCOL", "CEM_ID"
     FROM "LOAD"."LOADER_CELLS_STEP_1"
     INNER JOIN "LOAD"."META_DOCUMENTS" ON ("META_DOCUMENTS"."META_DOC_CODE"="LOADER_CELLS_STEP_1"."META_DOC_CODE")
     INNER JOIN "LOAD"."META_SECTIONS" ON ("META_SECTIONS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SECTIONS"."META_SECT_NAME"="LOADER_CELLS_STEP_1"."META_SECT_NAME")
     INNER JOIN "LOAD"."META_SETS" ON ("META_SETS"."META_SECT_ID"="META_SECTIONS"."META_SECT_ID") AND ("META_SETS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SETS"."META_SET_NAME"="LOADER_CELLS_STEP_1"."META_SET_NAME")
     INNER JOIN "LOAD"."USER_DEF_ATTRIBUTES" ON ("USER_DEF_ATTRIBUTES"."UDA_NAME"="LOADER_CELLS_STEP_1"."UDA_NAME")
     WHERE ("META_CELL_WUOM"=1)
     AND ("UDA_TYPE"='MATCH')
   ) "SELECTION"
  WHERE NOT EXISTS ( 
     SELECT *
     FROM "LOAD"."META_CELLS_UOM"
     WHERE ("SELECTION"."META_SET_ID"="META_CELLS_UOM"."META_SET_ID")
     AND ("SELECTION"."UDA_ID"="META_CELLS_UOM"."UDA_ID")
  )

目标表META_CELLS_UOM为空,源表LOADER_CELLS_STEP_1有大约80.000条记录,我从中选择大约3000条。

编辑2:

没有cuncurrent查询。当程序挂起执行上述查询时,这是来自SQL Server Mngmt Studio的Activity监视器的屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:0)

在没有查看exceution计划的情况下,我认为查询有时需要更长时间的原因是SQL服务器尝试使用上一个查询中的统计信息来削减一些cornor,但它会逆火

我会说,如果你

应该解决
  1. 首先在子查询中选择3000行LOADER_CELLS_STEP_1,然后加入其他数据,否则服务器可能会认为其他表更好,然后加入所有80000行,然后对其进行过滤。
  2. 跳过“not exists”子句并以另一种方式编写,例如使用META_CELLS_UOM的左外连接,并且只包含不匹配的行。并且这里也将它作为单独的子查询来避免错误的优化。
  3. 试试这个(我不知道我是否理解正确的关系)我可能错过了几个铃声,但我希望你理解。

    INSERT INTO "LOAD"."META_CELLS_UOM" WITH (ROWLOCK) 
    ("UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID") 

    SELECT "UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID" FROM ( SELECT "META_DOCUMENTS"."UDA_DOMAIN_ID", "META_DOCUMENTS"."META_DOC_ID", "META_SECTIONS"."META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_ROW" AS "META_CELL_UROW", "META_CELL_COL" AS "META_CELL_UCOL", "CEM_ID" FROM ( select * from "LOAD"."LOADER_CELLS_STEP_1" where ("META_CELL_WUOM"=1) AND ("UDA_TYPE"='MATCH') ) LCS INNER JOIN "LOAD"."META_DOCUMENTS" ON ("META_DOCUMENTS"."META_DOC_CODE"=LCS."META_DOC_CODE") INNER JOIN "LOAD"."META_SECTIONS" ON ("META_SECTIONS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SECTIONS"."META_SECT_NAME"=LCS."META_SECT_NAME") INNER JOIN "LOAD"."META_SETS" ON ("META_SETS"."META_SECT_ID"="META_SECTIONS"."META_SECT_ID") AND ("META_SETS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SETS"."META_SET_NAME"=LCS."META_SET_NAME")

    ) "SELECTION" left outer join "LOAD"."META_CELLS_UOM" on ("SELECTION"."META_SET_ID"="META_CELLS_UOM"."META_SET_ID") AND ("SELECTION"."UDA_ID"="META_CELLS_UOM"."UDA_ID") where "META_CELLS_UOM"."META_SET_ID" is null )