0

어디서나 500-1000 개 오브젝트가 포함 된 장고 쿼리 세트를 반복합니다. 해당 모델/테이블에도 7 개의 필드가 있습니다. 문제는 응용 프로그램에서 수행해야하는 다른 모든 데이터 처리를 고려할 때 너무 길게 반복되는 데 약 3 초가 걸리는 것입니다. 편집django 쿼리 세트를 천천히 반복하십시오.

: 여기 내 모델 :

class Node(models.Model): 
     node_id = models.CharField(null=True, blank=True, max_length=30) 
     jobs = models.TextField(null=True, blank=True) 
     available_mem = models.CharField(null=True, blank=True, max_length=30) 
     assigned_mem = models.CharField(null=True, blank=True ,max_length=30) 
     available_ncpus = models.PositiveIntegerField(null=True, blank=True) 
     assigned_ncpus = models.PositiveIntegerField(null=True, blank=True) 
     cluster = models.CharField(null=True, blank=True, max_length=30) 
     datetime = models.DateTimeField(auto_now_add=False) 

이 매우 빠르게 내 초기 쿼리입니다 :

timestamp = models.Node.objects.order_by('-pk').filter(cluster=cluster)[0] 
    self.nodes = models.Node.objects.filter(datetime=timestamp.datetime) 

그러나, 나는 반복 가서 3 초 정도 걸립니다,

def jobs_by_node(self): 
    """returns a dictionary containing keys that 
     are strings of node ids and values that 
     are lists of the jobs running on that node.""" 
    jobs_by_node = {} 

    #iterate over nodes and populate jobs_by_node dictionary 
    tstart = time.time() 
    for node in self.nodes: 
     pass #I have omitted the code because the slowdown is simply iteration 
    tend = time.time() 
    tfinal = tend-tstart 
    return jobs_by_node 

다른 방법 :

012 아래와 같이 나는 두 가지 방법을 시도했습니다
all_nodes = self.nodes.values('node_id') 
    tstart = time.time() 
    for node in all_nodes: 
     pass 
    tend = time.time() 
    tfinal = tend-tstart 

this 게시물을 참조하여 두 번째 방법을 시도했지만, 여전히 내 반복이 한 비트 빨라지지 않았습니다. 나는 웹을 아무 쓸데없이 닦았다. 이 프로세스를 최적화하는 데 큰 도움이 될 것입니다. 고맙습니다.

참고 : 나는 장고 버전 1.5을 사용하고 파이썬 2.7.3

+0

첫 번째 질문은'DEBUG = True'입니까? 둘째, 문제없이 반복적으로 문제가없는 25 만 개 개체를 포함하는 쿼리 세트를 반복하는 상황에서 장고를 사용 했으므로 문제가 반복되는 것입니다. 문제는 루프의 중간에서 무엇을 하든지간에 (패스를 넣는 부분) 가장 가능성이 높습니다. 또한, 외래 키를 걸을 경우'select_related'를 사용하는 코드 속도가 빨라지지만, 더 자세한 내용을 보지 않아도 문제가 무엇인지 알려주지 않아도됩니다. 마지막으로'pk' 명령으로 사용하지 마십시오. –

+0

개발로 인해 DEBUG = True를 사용하고 있으며 루프에 "pass"를 넣어서 타이밍을 실행했습니다. tfinal 때까지 for 루프를 시작하는 줄 (패스가 루프에서 유일 함)은 3 초가 걸립니다. 그래서 그만큼 큰 데이터 세트가 아니기 때문에 저는 당황 스럽습니다. 감사. –

+0

'DEBUG = True'로 코드를 수행하지 마십시오. 타이밍에 영향을주는 캐싱과 함께 많은 일들이 뒤에서 발생합니다. –

답변

1

확인 발급 된 SQL 쿼리하고있다. 당신은 print 문을 사용할 수 있습니다 :

SELECT id, jobs, ... FROM app_node 

그런 EXPLAIN SELECT id, jobs, ... FROM app_node를 실행하고 정확히 무엇이 잘못되었는지 알 : 당신에게 뭔가를 제공해야

print self.nodes.query # in general: print queryset.query 

.


당신이 예에 대해 생각할 수있는, 당신은 문제가 EXPLAIN 실행 한 후 무엇인지 알고 있다고 가정하고, 인덱스를 추가하는 등의 간단한 솔루션은 충분하지 않습니다 Cron 작업 또는 Celery 작업에서 X 분마다 관련 테이블을 별도의 테이블로 가져 와서 응용 프로그램에서 해당 테이블을 사용합니다.

PostgreSQL을 사용하는 경우 materialized views을 사용하고 unmanaged Django model에 "포장"할 수도 있습니다.

+0

나는 이것을 시험해 보겠다. 그러나 내가 위에서 논한 것처럼 나는 테이블에 1 백만개의 엔트리가 있고 더 최근의 엔트리 중 500-1000 개를 걸러 내고 있다고 생각한다. 필자는 현재 데이터를위한 하나의 테이블과 내 애플리케이션에서 간과 할 필요가없는 역사적인 테이블을 가질 수 있습니다. 모든 좋은 제안과 통찰력. 시간과 도움을 감사하십시오. 감사. –

+0

그게 전부 요 - EXPLAIN이 알려줄 것입니다. 어떤 색인이 누락 되었습니까? 그렇다면 문제를 해결할 수 있습니다. –

관련 문제