【发布时间】:2013-08-21 06:54:22
【问题描述】:
在 Windows XP SP3 下的 MS SQL Server 2008 R2 中有数百万条记录的数据库。
我的同事编写了一个 .Net 应用程序,它直接连接到这个数据库并运行合理数量的查询。我不知道.Net,但我确信这个应用程序没有使用 ODBC 连接到数据库。
另一方面,我编写了一个命令行 python(CPython 版本 2.7.5)应用程序,它连接到该数据库并在其上运行简单的查询,以通过 Internet 将数据发送到其他地方。使用 pyodbc 3.0.7(来自 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 的安装程序)和使用 SQL Server Native Client 10.0 驱动程序的 DSN 建立数据库连接。我已经尝试在 Windows Data Sources (ODBC) 小程序的 Connection Pooling 选项卡中禁用和启用此驱动程序的连接池。该脚本从 db 发送 100 条记录,然后关闭连接并休眠 2 分钟,然后再次运行。
这两个程序都在与 db 相同的机器上持续运行。
问题是当我删除定义的 DSN 时 .Net 应用程序运行良好(当然 python 脚本没有运行)。当我再次定义 DSN 并启动 python 脚本以并行运行 .Net 应用程序时,大约 5 小时没有问题。但随后逐渐地,当 python 脚本基本正常时,.Net 应用程序开始从数据库中获取超时。
发生这种情况会出什么问题?
编辑:
python 脚本(使用 ODBC 连接)一直运行良好。但是 .Net 应用程序在几个小时后就落后于通常的性能。当我关闭 python 脚本时,.Net 应用程序仍然落后。但是当我删除我为 python 脚本定义的 ODBC DSN 时,.Net 应用程序恢复正常性能。这很奇怪。正如我所说我对.Net一无所知,所以这可能是.Net应用程序的非标准代码的结果,可能是打开的事务、锁定、太多的连接等。为了让这个案例变得陌生,切割通过删除记录和重建索引将数据库大小减半,到目前为止似乎已经解决了 .Net 应用程序的问题。
编辑 2:
python 脚本运行的仅有的两个查询是:
SELECT TOP 100 FROM tbl_data WHERE id > ? ORDER BY id
和
SELECT * FROM tbl_data WHERE id = ?
第一个查询通常只在每次运行 python 脚本时运行一次。第二个最多运行 100 次。 id 是主键,因此被索引。如您所见,查询再简单不过了。对于第一个查询,我阅读了程序中的整个结果集,以便不在数据库服务器上保持游标打开。此外,我已经为我正在使用的驱动程序关闭了 ODBC 小程序中的连接池,因此在每次运行脚本后,数据库连接应该已经被释放,并且数据库服务器上的所有资源都应该被释放。脚本休眠 2 分钟,然后重复此操作。
.Net 应用程序运行的查询要复杂得多,再加上数据库上的一些触发器。奇怪的是它本身运行得很好。但是在定义 DSN 后,它开始在单个插入语句上等待很长时间,这有时会导致超时。
另外我应该说 Windows 和 MSSQL 没有更新微软的最新补丁,所以如果它是 ODBC 驱动程序或 MSSQL 本身的错误,它可能已经为其他人解决了。
编辑 3
表聚集在 PK 索引上。数据表现在包含大约 150 万条记录。数据库大小约为 160GB。服务器没有高规格。 Intel Core i7 2600、4GB RAM、普通 1TB SATA 磁盘驱动器。
【问题讨论】:
-
非常感谢您的更新。主键是集群的还是非集群的?另外这台服务器有多大(内存、cpu 等)?
-
我编辑了问题
-
根据您所描述的所有内容,您的 python (ODBC) 应用程序似乎由于资源争用而阻塞了 .Net 应用程序。超时只能由一些事情引起,资源争用、长时间运行的查询和阻塞是通常的嫌疑人。当性能下降时,您是否查看了活动连接以查看是否存在阻塞问题。
标签: python .net sql-server odbc pyodbc