pd.read_sql对于某些类型的首次查询速度较慢

问题描述 投票:0回答:2

当我从某些类型的SQL查询读取数据到pandas数据帧时,我遇到了性能问题。我首先使用以下代码在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 var3 = '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秒。

我想这与SQL DB有关?有人可以解释为什么我看到这种情况吗?有什么方法可以防止第一个查询花费更长的时间?

sql pandas pyodbc
2个回答
1
投票

对于此查询:

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

我建议在(var2, var3, var4, var1)上建立索引。然后,查询将使用此索引查找所需的行。如果结果集很大,查询仍会花费很长时间。

就是说,您面临的问题听起来像是“冷缓存”问题。您没有指定数据库,但是通常,数据库开始时内存中没有数据。当您获取数据页或索引页时,数据库会将它们缓存在内存中,因此后续访问要快得多。


0
投票

正如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(*)而不是*来看到性能提高。

希望这对您有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.