Pergunta

Eu tenho uma visão Django que cria 500-5000 novas pastilhas de banco de dados em um loop. O problema é que é muito lento! Estou recebendo cerca de 100 inserções por minuto em Postgres 8.3. Nós costumávamos usar MySQL em menos hardware (menor instância EC2) e nunca teve esses tipos de problemas de velocidade.

Detalhes: Postgres 8.3 no Ubuntu Servidor 9,04. Server é um "grande" Amazon EC2 com banco de dados sobre EBS (ext3) -. 11GB / 20GB

Aqui está um pouco da minha postgresql.conf - deixe-me saber se você precisar de mais

shared_buffers = 4000MB
effective_cache_size = 7128MB

O meu 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()

Alguns saída do topo:

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 

Deixe-me saber se quaisquer outros detalhes seria útil.

Foi útil?

Solução

Em primeiro lugar, as operações ORM são sempre vai ser mais lento do que o SQL puro. Uma vez escrevi uma atualização para um grande banco de dados em código ORM e configurá-lo correr, mas abandonou-o após várias horas quando ele tinha completado apenas uma pequena fração. Depois de reescrever-lo em SQL toda a coisa correu em menos de um minuto.

Em segundo lugar, tenha em mente que o seu código aqui está fazendo até quatro operações de banco de dados separados para cada linha em seu conjunto de dados - o get em get_or_create, possivelmente também o create, o count no filtro, e finalmente o save. Isso é um monte de acesso de banco de dados.

Tendo em conta que um máximo de 5000 objetos não é enorme, você deve ser capaz de ler todo o conjunto de dados na memória no início. Então você pode fazer um único filter para obter todas as palavras-chave existentes objetos de uma só vez, economizando um grande número de consultas no get_or_create palavras-chave e também evitando a necessidade de instanciar ProfileKeywords duplicados em primeiro lugar.

Outras dicas

Uma razão comum para operações em massa lentos como esta é cada inserção acontecendo em sua própria transação. Se você pode obter todos eles para acontecer em uma única transação, que poderia ir muito mais rápido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top