【发布时间】:2010-08-25 12:59:23
【问题描述】:
我正在开发一个系统,它会定期(每天 4-5 次)运行一个 select 语句,该语句通常需要不到 10 秒,但定期最多需要 40 分钟。
数据库在 Windows Server 2008 + SQL Server 2008 R2 上;都是64位的。
在运行数据库的机器上有一个服务轮询数据库并为需要它的记录生成值。然后,使用 MFC CRecordset 类从用 C++(VS 2010)编写的第二台机器上的服务中使用多表连接选择定期查询这些记录,以提取数据。导致问题的查询示例如下所示。
SELECT DISTINCT "JobKeysFrom"."Key" AS "KeyFrom","KeysFrom"."ID" AS "IDFrom",
"KeysFrom"."X" AS "XFrom","KeysFrom"."Y" AS "YFrom","JobKeysTo"."Key" AS "KeyTo",
"KeysTo"."ID" AS "IDTo","KeysTo"."X" AS "XTo","KeysTo"."Y" AS "YTo",
"Matrix"."TimeInSeconds","Matrix"."DistanceInMetres","Matrix"."Calculated"
FROM "JobKeys" AS "JobKeysFrom"
INNER JOIN "JobKeys" AS "JobKeysTo" ON
("JobKeysFrom"."Key"<>"JobKeysTo"."Key") AND
("JobKeysFrom"."JobID"=531) AND
("JobKeysTo"."JobID"=531)
INNER JOIN "Keys" AS "KeysFrom" ON
("JobKeysFrom"."Key"="KeysFrom"."Key") AND ("JobKeysFrom"."Status"=4)
INNER JOIN "Keys" AS "KeysTo" ON
("JobKeysTo"."Key"="KeysTo"."Key") AND ("JobKeysTo"."Status"=4)
INNER JOIN "Matrix" AS "Matrix" ON
("Matrix"."IDFrom"="KeysFrom"."ID") AND ("Matrix"."IDTo"="KeysTo"."ID")
ORDER BY "JobKeysFrom"."Key","JobKeysTo"."Key"
我已经尝试了以下
- 检查了索引,所有索引看起来都是正确的,它们是活动的,并且正在根据查询使用
- 设计顾问回来时没有任何建议
- 我已尝试对索引和数据进行碎片整理
- 通过导出数据并将其重新导入新数据库,从头开始重建数据库。
- 对其运行分析器,发现当它出错时,它似乎执行了数百万(高达 1 亿)次读取,而不是几十万次。
- 在不同的服务器上运行数据库
在运行查询期间,我可以在管理工作室窗口中运行完全相同的查询,它将在 10 秒内恢复运行。问题似乎与锁、死锁、CPU、磁盘或内存无关,因为它在运行数据库的机器只运行这一个查询时已经完成了。服务器有 4 个处理器和 16 GB 内存来运行它。我还尝试将磁盘升级到更快的磁盘,但没有效果。
在我看来,就好像数据库接收到查询,开始处理它,然后进入休眠状态 40 分钟或在不使用索引的情况下运行查询。
当需要很长时间时,它最终会完成并将查询结果(通常约为 70-100000 条记录)发送回调用应用程序。
任何帮助或建议将不胜感激,非常感谢
【问题讨论】:
-
此查询是否作为参数化存储过程运行?
-
你能避免SELECT DISTINCT吗?这会严重影响性能。
-
@Yves:听起来它的性能足以运行 adhoc,并在 10 秒内返回。
-
你能用 TOP 100 试试,看看在服务中执行速度是否更快?
-
谁可以更改状态字段 (Status=4)???
标签: sql-server sql-server-2008 performance