1

问题

我正在尝试使用 python 读取 MS SQL Server 中的表,特别是 SQLalchemy、pymssql 和 pandas.read_sql。我想执行查询,将结果放入 pandas Dataframe,并以合理的速度继续我的一天,但是一个相当简单的查询(输出 = 100 MB)在使用以太网的 LAN 连接上需要将近 5-10 分钟电缆 - 看不到 wifi。

生成的包含 3 列和 3214086 个条目的数据帧耗时 423 秒。以下信息():

Int64Index: 3214086 entries, 0 to 3214085
Data columns (total 3 columns):
DateTime    datetime64[ns]
TagName     object
Value       float64
dtypes: datetime64[ns](1), float64(1), object(1)
memory usage: 98.1+ MB
None

如果我的数学是正确的,423 秒内 100 MB 大约是 230 kB/s,我认为通过以太网连接的速度非常慢。瓶颈一定在sql server本身


查询信息

SQL 服务器本身是一个 Wonderware 设置,可能与它有关,也可能无关。在以下查询中,我要求在 1 个月的时间跨度内提供 6 个不同标签的值,其中分辨率为 5000 毫秒或 5 秒。

以下是查询本身的样子:

sql_query = '''
SELECT DateTime, TagName, Value

    FROM Runtime.dbo.AnalogHistory

    WHERE
        DateTime BETWEEN '2014-05-26 00:00' AND '2014-06-26 00:00'
    AND 
        TagName IN (
            'Tag1.ActualValue', 
            'Tag2.ActualValue', 
            'Tag3.ActualValue', 
            'Tag4.ActualValue', 
            'Tag5.ActualValue', 
            'Tag6.ActualValue')
    AND
        wwRetrievalMode = 'Cyclic'
    AND
        wwResolution = 5000
'''

最后,executeQuery 函数:

import pandas as pd
import pymssql
import sqlalchemy

def executeQuery(sql_query):
    connection_string = 'mssql+pymssql://user:password@server'
    engine = sqlalchemy.create_engine(connection_string)

    df = pd.read_sql(sql_query, engine)

    if 'DateTime' in df.columns:
        df.DateTime = pd.to_datetime(df.DateTime, infer_datetime_format=True)

    return df

问题

这里发生了什么?这是我正在使用的一个包中的限制,还是我可以用我所拥有的来加快速度?

这个问题似乎与 OP 试图写入 sql 服务器有关。那里说使用 'BULK INSERT' 而不是通过使用 .csv 文件的 pandas 更快,但这不是从 sql 服务器读取的可行选项。我是否应该有一个包含所有日期/时间和所有标签的 .csv 文件的目录!?这首先会否定 sql server 的使用,不是吗?

4

1 回答 1

2

我猜你是executeQuery()在循环调用你的函数 - 很多次,每次你重新创建一个 SQLAlchemy 引擎,这使它变慢。

因此,尝试创建一次数据库连接并多次使用它:

import pandas as pd
import pymssql
import sqlalchemy

connection_string = 'mssql+pymssql://user:password@server'
engine = sqlalchemy.create_engine(connection_string)

def executeQuery(sql_query, engine=engine):
    df = pd.read_sql(sql_query, engine)

    # i'm not sure that you really need it ...
    if 'DateTime' in df.columns:
        df.DateTime = pd.to_datetime(df.DateTime, infer_datetime_format=True)

    return df

PS 如果您DateTime在 MS SQL 端的列是 DateTime 数据类型,SQLAlchemy 应该将其映射到 Pythondatetime类型。所以最后应该已经np.datetime64...

如果您调用它一次或很少几次,那么我会执行以下操作:

  • 检查执行计划(使用的索引、数据偏度等)
  • 在 MS SQL 服务器上执行此查询 - 并测量执行时间
  • 通过网络在您的客户端计算机上执行此查询 - 并测量执行时间

在那之后你会看到你最多在哪里浪费时间......

于 2016-06-20T15:59:26.610 回答