大型 select 查询在使用 Python 和 unixODBC 连接到 SQL 服务器时挂起
Large select query hangs using Python and unixODBC connecting to SQL Server
我们必须 运行 大量 select 对来自 CentOS 6 机器的 SQL 服务器的查询。在两台服务器上,当使用相当平淡的 select 语句时,从 SQL 服务器返回的数据速率开始很快,然后减慢速度并每 ~30 秒接收一次突发数据。在另外两台服务器上,查询 运行 始终如一并在不到 2 分钟内完成。 unixODBC 和 msodbcsql 的所有这些盒子上的配置完全相同。
导致问题的示例代码:
import datetime
import pyodbc
db_connection_string = '<connection string info>'
print(datetime.datetime.now(), 'Connecting to db...')
db_connection = pyodbc.connect(db_connection_string, autocommit=True)
print(datetime.datetime.now(), '...connected')
cursor = db_connection.cursor()
try:
sql_statement = 'SELECT data FROM table;'
num = 0
print(datetime.datetime.now(), 'Iterating over cursor...')
for row in cursor.execute(sql_statement):
num += 1
if num % 100000 == 0:
print(datetime.datetime.now(), num)
print(datetime.datetime.now(), num)
print(datetime.datetime.now(), '...iteration completed')
finally:
cursor.close()
db_connection.close()
这使用了 unixODBC 2.3.0
和 msodbc 11.0.2270.0
。服务器是 CentOS 6.5/6.6
和 Python 3.4
.
我们已经尝试过:
- 监控系统资源,没有内存峰值或 CPU 使用,除非正在处理数据
- 进程上的 strace 也仅在处理数据时显示更改
- SQL 服务器和 Python 服务器似乎都挂起并等待对方做某事
- 监控网络流量也显示没有峰值或包被丢弃或任何错误
- scp 和 sftp'ing 文件到服务器和服务器之间没有问题
- 使用相同的查询连接到不同的数据库类型没有问题
- 重写 Java 和 运行 中的代码在有问题的服务器上有同样的问题,但 运行 在好的服务器上没问题
如果有任何其他有助于解决此问题的想法,我们将不胜感激。
问题似乎是 SQL 服务器上的驱动程序交互不能很好地与 CentOS 兼容。更改驱动程序设置可防止查询挂起,尽管与其他服务器相比,在性能最佳的服务器上返回结果的速度仍然快 4 倍。这里的教训似乎是奇怪的驱动程序交互可能会想出尝试使用 MS 和 Linux 系统的组合。
我们必须 运行 大量 select 对来自 CentOS 6 机器的 SQL 服务器的查询。在两台服务器上,当使用相当平淡的 select 语句时,从 SQL 服务器返回的数据速率开始很快,然后减慢速度并每 ~30 秒接收一次突发数据。在另外两台服务器上,查询 运行 始终如一并在不到 2 分钟内完成。 unixODBC 和 msodbcsql 的所有这些盒子上的配置完全相同。
导致问题的示例代码:
import datetime
import pyodbc
db_connection_string = '<connection string info>'
print(datetime.datetime.now(), 'Connecting to db...')
db_connection = pyodbc.connect(db_connection_string, autocommit=True)
print(datetime.datetime.now(), '...connected')
cursor = db_connection.cursor()
try:
sql_statement = 'SELECT data FROM table;'
num = 0
print(datetime.datetime.now(), 'Iterating over cursor...')
for row in cursor.execute(sql_statement):
num += 1
if num % 100000 == 0:
print(datetime.datetime.now(), num)
print(datetime.datetime.now(), num)
print(datetime.datetime.now(), '...iteration completed')
finally:
cursor.close()
db_connection.close()
这使用了 unixODBC 2.3.0
和 msodbc 11.0.2270.0
。服务器是 CentOS 6.5/6.6
和 Python 3.4
.
我们已经尝试过:
- 监控系统资源,没有内存峰值或 CPU 使用,除非正在处理数据
- 进程上的 strace 也仅在处理数据时显示更改
- SQL 服务器和 Python 服务器似乎都挂起并等待对方做某事
- 监控网络流量也显示没有峰值或包被丢弃或任何错误
- scp 和 sftp'ing 文件到服务器和服务器之间没有问题
- 使用相同的查询连接到不同的数据库类型没有问题
- 重写 Java 和 运行 中的代码在有问题的服务器上有同样的问题,但 运行 在好的服务器上没问题
如果有任何其他有助于解决此问题的想法,我们将不胜感激。
问题似乎是 SQL 服务器上的驱动程序交互不能很好地与 CentOS 兼容。更改驱动程序设置可防止查询挂起,尽管与其他服务器相比,在性能最佳的服务器上返回结果的速度仍然快 4 倍。这里的教训似乎是奇怪的驱动程序交互可能会想出尝试使用 MS 和 Linux 系统的组合。