【问题标题】:Query in a batch takes from few millisec to 2 minutes on SQL Server在 SQL Server 上批量查询需要几毫秒到 2 分钟
【发布时间】:2014-01-01 01:38:43
【问题描述】:

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

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

由于可以从已有配置入手,所以需要合并两个配置,所以临时表有的在事务外填充,有的在事务中填充。

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

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

我一开始以为是死锁,将查询超时提高到 3 分钟,最终在 2 分钟左右执行完毕。我再说一遍,这些查询有时会在几毫秒内执行。

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

使用分析器和活动监视器监视 SQL Server 我没有发现任何奇怪的东西。
CPU没挂,有内存,磁盘读大概0,磁盘写0-200kb/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:

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

【问题讨论】:

  • @SQLhint.com 查看编辑
  • 怎么知道有随机锁?您是否同时运行任何其他进程?它不可能是死锁,因为死锁是通过杀死其中一个进程立即解决的。
  • @Szymon 我知道这是随机,因为它并不总是挂在同一个查询上,有时它根本不会挂起。该架构上没有其他进程正在运行。
  • 但是你怎么知道它们实际上是锁?您在查询运行时检查过锁吗?还是被阻止的进程?
  • @usr 在日志中我发现了其中一些行:Autogrow of file 'LOAD_log' in database 'LOAD' took 116625 milliseconds. Consider using ALTER DATABASE to set a smaller FILEGROWTH for this file.。会不会和挂机有关?

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


【解决方案1】:

在没有查看执行计划的情况下,我认为查询有时需要更长时间的原因是 SQL 服务器试图使用上次查询的统计信息来减少一些角落,但结果适得其反

我会说如果你应该解决它

  1. 先选择子查询中的 3000 行 LOADER_CELLS_STEP_1 并加入其他数据,否则服务器可能会认为其他表更好,然后将所有 80000 行加入,然后过滤。
  2. 跳过“不存在”子句并以另一种方式编写它,例如使用 META_CELLS_UOM 进行左外连接,并且只包含不匹配的行。并且在这里也将其作为单独的子查询来避免不良优化。

试试这个(我不知道我是否理解正确的关系),我可能错过了一些提示,但我希望你能理解。

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”)

选择“UDA_DOMAIN_ID”、“META_DOC_ID”、“META_SECT_ID”、“META_SET_ID”、“UDA_ID”、“META_CELL_UROW”、“META_CELL_UCOL”、“CEM_ID” 从 ( 选择“META_DOCUMENTS”、“UDA_DOMAIN_ID”、“META_DOCUMENTS”、“META_DOC_ID”、“META_SECTIONS”。“META_SECT_ID”、“META_SET_ID”、“UDA_ID”、“META_CELL_ROW”作为“META_CELL_UROW”、“META_CELL_COL”作为“META_CELL_UCOL”、“ CEM_ID" 从 ( 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")

) "选择" 左外连接 "LOAD"."META_CELLS_UOM" on ("SELECTION"."META_SET_ID"="META_CELLS_UOM"."META_SET_ID") AND ("SELECTION"."UDA_ID"="META_CELLS_UOM"."UDA_ID") 其中“META_CELLS_UOM”。“META_SET_ID”为空 )

【讨论】:

  • 谢谢,我试试。抱歉回复晚了,但我正在度假。
猜你喜欢
  • 2014-12-17
  • 2020-07-19
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
相关资源
最近更新 更多