pd.read\u sql slow

dwthyt8l  于 2021-08-09  发布在  Java
关注(0)|答案(2)|浏览(495)

当我将某些类型的sql查询中的数据读取到Dataframe中时,我遇到了性能问题。我首先使用如下代码在azure中查询sql db:

cnxn = pyodbc.connect(db_conn_str)
starttime = timeit.default_timer()   
sql = "Select * from table where var1 != 'a' and var2 = 'b' and var3 = 'c' and var4 = 'd'"
outdata = pd.read_sql(sql, cnxn)   
print("Elapsed time :", timeit.default_timer() - starttime)

这通常需要20-30秒。如果我重新运行上面的查询,或者如果我在接下来的20分钟左右运行另一个查询,其中“a”、“b”、“c”和“d”是不同的,那么查询只需要大约0.5秒。20分钟后,此类型的下一个查询将花费20-30秒。
其他类型的查询需要更短的时间(例如,我只限制使用var2的查询),我已经尝试先运行这些查询,但是使用上述代码的第一个查询仍然需要20-30秒。
我想这和sqldb有关吧?有人能解释一下为什么我会看到这种情况吗?有什么方法可以避免第一个查询花费这么长的时间吗?

r9f1avp5

r9f1avp51#

对于此查询:

select *
from table
where var1 <> 'a' and var2 = 'b' and var3 = 'c' and var4 = 'd'

我推荐一个关于 (var2, var3, var4, var1) . 然后,查询将使用此索引来查找所需的行。如果结果集很大,查询仍然需要很长时间。
也就是说,你面临的问题听起来像是一个“冷缓存”问题。您不指定数据库,但一般来说,数据库开始时内存中没有数据。当您获取数据页或索引页时,数据库会将它们缓存在内存中,以便后续访问速度更快。

ymdaylpp

ymdaylpp2#

正如gordon指出的,索引很重要,您需要解决sql语句中的冲突。你是这个意思吗?

sql = "Select * from table where var1 != 'a' and var2 = 'b' and (var3 = 'c' OR var3 = 'd')"

此外,考虑是否需要所有这些语句也是一个好主意。有多少行,其中var1是a,var2不是b,var3不是c或d?如果它是一个非常小的数字,您可能需要考虑在代码中而不是在sql语句中过滤结果。
有时,您可以通过where子句中的子查询(where var in(a,b,c)和var not in(b,e)),或者通过选择单个列或count()而不是,看到性能的提高。
希望这对您有所帮助:)

相关问题