迭代大型列表时Python很慢

时间:2012-02-22 19:59:50

标签: python sql database pyodbc

我目前正在使用pyodbc从数据库中选择一个大型行列表。然后将结果复制到一个大型列表,然后我尝试迭代列表。在我放弃python并尝试在C#中创建它之前,我想知道是否有一些我做错了。

clientItems.execute("Select ids from largetable where year =?", year);
allIDRows = clientItemsCursor.fetchall() #takes maybe 8 seconds.

for clientItemrow in allIDRows:
    aID = str(clientItemRow[0])
    # Do something with str -- Removed because I was trying to determine what was slow
    count = count+1

更多信息:

  • for循环当前以每秒约5个循环运行,这对我来说似乎非常慢。
  • 选择的总行数为~489,000。
  • 它运行的机器有很多RAM和CPU。它似乎只运行一个或两个核心,而ram是1.72GB的4gb。

谁能告诉我什么错了?脚本运行得这么慢吗?

由于

5 个答案:

答案 0 :(得分:18)

对于Python本机列表来说,这应该不会很慢 - 但是ODBC的驱动程序可能会返回一个“懒惰”对象,该对象试图变得聪明但只是变慢。试试吧

allIDRows = list(clientItemsCursor.fetchall())

在您的代码中并发布更多基准。

(如果你开始在中间插入内容,Python列表可能会变慢,但只是快速遍历大型列表)

答案 1 :(得分:1)

它可能很慢,因为您首先将所有结果加载到内存中并在列表上执行迭代。尝试迭代光标。

不,脚本不应 慢。

clientItemsCursor.execute("Select ids from largetable where year =?", year);
for clientItemrow in clientItemsCursor:
    aID = str(clientItemrow[0])
    count = count + 1

答案 2 :(得分:1)

此处需要进行更多调查......请考虑以下脚本:

bigList = range(500000)
doSomething = ""
arrayList = [[x] for x in bigList]  # takes a few seconds
for x in arrayList:
    doSomething += str(x[0])
    count+=1

这与您的脚本几乎相同,减去数据库的内容,并且需要几秒钟才能在我非常快的机器上运行。

答案 3 :(得分:0)

当你直接连接数据库时(我的意思是你得到一个SQL提示符),有多少个secods运行这个查询?

当查询结束时,您会收到如下消息:

NNNNN rows in set (0.01 sec)

所以,如果那个时间太大,而你的查询速度很慢,那么你可能需要在该表上创建一个索引。

答案 4 :(得分:0)

这很慢,因为你是

  1. 获得所有结果
  2. 分配内存并将值分配给该内存以创建列表allIDRows
  3. 迭代该列表并计算。
  4. 如果执行给你一个光标,那么使用光标有利于它,并在你收回东西时开始计数并节省内存分配。

    clientItemsCursor.execute("Select ids from largetable where year =?", year);
    for clientItemrow in clientItemsCursor:
       count +=1
    

    其他提示:

    • 创建年度指数
    • 使用'select count(*)from ...来获取年度计数'这可能会在db上进行优化。
    • 如果不需要,删除aID行即使没有使用,也会将行的第一项转换为字符串。