2013-03-19 1 views
2

나는처럼 보이는 API에서 데이터를 검색 해요 :가능하면 테이블 스키마를 통해 쿼리 수를 줄입니까?

[{"type": "a", "value": 1, "identifier": 1}, 
{"type": "b", "value": 9, "identifier": 1}, 
{...},{...}, 
{"type": "a", "value": 2, "identifier": n}] 

이 식별자는 1-500 사이의 값이 될 수 있으며, 모든 레코드가 같은 식별자있을 것이라는 점을 보장 아니에요. 식별자가 있으면 동일한 유형 및 특정 범위의 값을 갖습니다. 내가 처음 레코드를 업데이트하기 위해 사용 된 것은이처럼 보였다 :

api_data.each do |x| 
    temp = Object.find_or_create_by_type_and_identifier_and_id(x["type]", x["identifier"], user_id) 
    temp.update_attributes(x) 
end 

이 매우 느리고, 약 2200 쿼리이 데이터가로드 될 때마다 실행. 한 번 데이터가 존재하는지 확인한 다음 한 번 업데이트하여 1100 개의 항목을 찾습니다.

create table (type, identifier, id, value) 

이것은 obviously inefficient, 내가 얼마나 그래서 몰랐어요 : 현재 사용중인 테이블 방식은 같다. 새 사용자 데이터를 업데이트하거나 가져와야 할 때 응용 프로그램이 크롤링하지 않도록 쿼리 수를 줄이려면 어떻게해야합니까?

제안 된 방법은 업데이트가 필요할 때 이전 항목을 대량 삽입하고 삭제하는 것입니다.이 경우 2로 줄일 수 있지만 가장 좋은 방법인지는 확실하지 않습니다.

+0

스테이징 테이블에 대량 삽입을 수행하고 메인 테이블을 업데이트하십시오. –

+0

또는 스레드를 사용하여 – phoet

답변

1

일괄 업데이트가 필요한 경우 업데이트의 특성에 따라 ActiveRecord::Relation#update_all으로 벗어날 수 있습니다.

activerecord-import gem은 효율적인 대량 삽입을 수행합니다. 업데이트 메커니즘이 있는지 확실하지 않지만 신속하게 삽입하는 것이 좋습니다 (수천 개의 행에 대해 단일 SQL 문). 누락 된 레코드를 삽입하기 위해 ~ 2200 레코드, 일부 업데이트 논리 및 단일 명령문에 대해 하나의 빠른 쿼리 만 사용합니다.

좀 더 극단적이긴하지만 훨씬 빠른 해결책은 DB의 모든 레코드를로드하고, 새 상태를 조정하고, 삭제 또는 변경하려는 모든 행을 삭제 (빠른 대량 작업)하고 대량 삽입 새롭거나 수정 된 것일 수 있습니다 activerecord-import를 가진 것들. 이는 최대 세 건의 데이터베이스 작업으로 ~ 2200 개의 레코드로 매우 빠르게 실행되지만 모든 변경 사항에 대해 신속하게 처리 할 수는 없습니다.

마지막으로 SQL을 사용할 수 있습니다. 변경 사항이 기본이므로 충분히 간단하게 YourModel.connection.execute "UPDATE some_things SET foo = 'whatever'" 할 수 있습니다. 난 네가 원하는대로 할 수있는 레일 티 (Railsy) 방법이 있다고 생각한다. ActiveRecord 설명서를 확인하십시오. delete_all, update_all 등과 같이 대량 작업이 많이 있습니다.

+0

업데이트를 수행하면 기본적으로 WHERE x = y가 수행됩니다.이 경우 데이터가 이기종이기 때문에이 경우 작동하지 않습니다. 위의 주석에서 언급 한 스테이징 아이디어에 대해 더 많이 살펴 보았습니다.하지만 지금 당장은 connection.execute를 사용하여이 문제를 해결하고 있습니다. 더 레일스 -ESC 응답을 원하지만, 지금까지 내가 할 일이다. – Sturm

관련 문제