2012-08-24 6 views
2

내 앱에서 쿼리를 최적화하는 과정에서 이상한 것으로 나타났습니다. 주어진 코드 섹션에서 객체를 가져 와서 일부 값을 업데이트 한 다음 저장합니다. 이론적으로 이것은 2 개의 쿼리를 실행해야합니다. 그러나 사실 3 개의 쿼리를 실행합니다. 1 개체를 얻을 때 쿼리를 선택하고 개체를 저장할 때 2 쿼리를 선택합니다 (다른 선택 및 업데이트). 하나의 검색어를 삭제하면 어리석은 것처럼 보일 수 있습니다. 이 특정 방법에서는 내가 저장하는 모든 쿼리가 DB에서 1 ​​회 적중되므로 메서드를 빠르게 처리해야하므로 많은 개체를 업데이트하고 있습니다.Django another optimizing save()

쿼리를 검사하면 두 개의 선택 쿼리가 다르며 첫 번째 쿼리는 여러 쿼리를 가져오고 같은 쿼리가 실행하는 선택은 간단합니다.

  myobject = room.myobjects.get(id=myobject_id) # one query executed here 
      myobject.color = color 
      myobject.shape = shape 
      myobject.place = place 
      myobject.save() # two queries executed here 

쿼리 : 여기

은 예제 코드입니다

1) "SELECT `rooms_object`.`id`, `rooms_object`.`room_id`, ......FROM `rooms_object` WHERE (`rooms_object`.`id` = %s AND `rooms_object`.`room_id` = %s)" 

    2) "SELECT (1) AS `a` FROM `rooms_object` WHERE `rooms_object`.`id` = %s LIMIT 1" 

    3) "UPDATE ......this ones obvious" 

나는 이미 메모리에 개체가 인식하는 방법을 저장하려면 그것은 다시받을 필요가 없습니다. ... 가능하다면 ...

답변

5

두 번째 쿼리는 실제로 개체를 다시 가져 오지 않습니다. UPDATE 쿼리를 수행하기 전에 id에서 매우 빠른 "존재"확인을 수행하고 있습니다. 해당 쿼리에서 반환되는 것은 모두 1이며 필드는 인덱싱되므로 매우 효율적이어야합니다.

이 방법으로 ORM을 디자인 한 이유는 먼저 개체에 ID가 있는지 확인하기 위해서입니다. 그렇다면 SELECT을 사용하여 실제로 데이터베이스에 여전히 존재하는지 확인하십시오. 업데이트가 있으면 업데이트를 수행합니다. 어떤 식 으로든 레코드가 존재하지 않으면 INSERT을 수행합니다. 장고를 알지 못하도록 객체를 생성 한 다음 데이터베이스에서 수동으로 행을 삭제하면이를 테스트 할 수 있습니다. 그런 다음 save()

이렇게하면 장고가 일관성을 유지하는지 확인할 수 있습니다.

새 개체 인 경우 개체에 id이 없는지 알기 때문에 하나의 INSERT 쿼리 만 받게됩니다.

+0

내가 tracelytics.com를 사용하여 추적을 수행하고 흥미로운 부분은 두 번째 쿼리는 약 1ms의 각 쿼리를 걸립니다. 따라서 매우 빠르지 만이 특정보기에는 1 초가 추가됩니다. 그러나 그것은 지금하고있는 일에 대해 많은 의미를 갖습니다. 감사. –

+0

보기가 1 초간 존재한다는 것을 의미하는 1000 건의 업데이트를하고 있다는 것을 의미합니까? – jdi

+0

네 맞습니다. –

관련 문제