我有一个Django视图,它在一个循环中创建了500-5000个新的数据库INSERTS。问题是,它真的很慢!我在Postgres 8.3上每分钟大约有100个插页。我们曾经在较小的硬件(较小的EC2实例)上使用MySQL,并且从未遇到过这些类型的速度问题。

详细说明: 在Ubuntu Server 9.04上发布Postgres 8.3。 服务器是“大”的。带有EBS(ext3)数据库的Amazon EC2 - 11GB / 20GB。

以下是我的一些postgresql.conf - 如果您需要更多

,请告诉我
shared_buffers = 4000MB
effective_cache_size = 7128MB

我的python:

for k in kw:
        k = k.lower()
        p = ProfileKeyword(profile=self)
        logging.debug(k)
        p.keyword, created = Keyword.objects.get_or_create(keyword=k, defaults={'keyword':k,})
        if not created and ProfileKeyword.objects.filter(profile=self, keyword=p.keyword).count():
            #checking created is just a small optimization to save some database hits on new keywords
            pass #duplicate entry
        else:
            p.save()

顶部的一些输出:

top - 16:56:22 up 21 days, 20:55,  4 users,  load average: 0.99, 1.01, 0.94
Tasks:  68 total,   1 running,  67 sleeping,   0 stopped,   0 zombie
Cpu(s):  5.8%us,  0.2%sy,  0.0%ni, 90.5%id,  0.7%wa,  0.0%hi,  0.0%si,  2.8%st
Mem:  15736360k total, 12527788k used,  3208572k free,   332188k buffers
Swap:        0k total,        0k used,        0k free, 11322048k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                            
14767 postgres  25   0 4164m 117m 114m S   22  0.8   2:52.00 postgres                                                                                                                                            
    1 root      20   0  4024  700  592 S    0  0.0   0:01.09 init                                                                                                                                                
    2 root      RT   0     0    0    0 S    0  0.0   0:11.76 migration/0                                                                                                                                         
    3 root      34  19     0    0    0 S    0  0.0   0:00.00 ksoftirqd/0                                                                                                                                         
    4 root      RT   0     0    0    0 S    0  0.0   0:00.00 watchdog/0                                                                                                                                          
    5 root      10  -5     0    0    0 S    0  0.0   0:00.08 events/0                                                                                                                                            
    6 root      11  -5     0    0    0 S    0  0.0   0:00.00 khelper                                                                                                                                             
    7 root      10  -5     0    0    0 S    0  0.0   0:00.00 kthread                                                                                                                                             
    9 root      10  -5     0    0    0 S    0  0.0   0:00.00 xenwatch                                                                                                                                            
   10 root      10  -5     0    0    0 S    0  0.0   0:00.00 xenbus                                                                                                                                              
   18 root      RT  -5     0    0    0 S    0  0.0   0:11.84 migration/1                                                                                                                                         
   19 root      34  19     0    0    0 S    0  0.0   0:00.01 ksoftirqd/1 

如果有任何其他细节会有帮助,请告诉我。

有帮助吗?

解决方案

首先,ORM操作总是比纯SQL慢。我曾经在ORM代码中写了一个大型数据库的更新并将其设置为运行,但是在几小时后它只完成了一小部分就退出了。在SQL中重写之后,整个事情都在不到一分钟的时间内完成。

其次,请记住,这里的代码对数据集中的每一行最多进行四次单独的数据库操作 - get_or_create中的 get ,也可能是 create ,过滤器上的 count ,最后是 save 。这是很多数据库访问。

请记住,最多5000个对象并不大,您应该能够在开始时将整个数据集读入内存。然后你可以做一个过滤器来一次性获取所有现有的Keyword对象,在Keyword get_or_create 中保存了大量的查询,同时也避免了实例化重复的需要ProfileKeywords首先。

其他提示

像这样的缓慢批量操作的一个常见原因是每个插入都发生在它自己的事务中。如果您可以在一次交易中完成所有这些操作,那么它可以更快。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top