2010-01-29 2 views
5

DB에서 각 고객에 대해 한 번씩 레일스 앱에서 수천 번 실행중인 계산 계산 쿼리가 있습니다.레일 MySQL 쿼리 시간 혼동

쿼리 캐시를 비활성화 한 상태에서 MySQL 클라이언트에서 쿼리를 실행하면 쿼리가 1ms 이상 걸릴 수 있습니다.

그러나 쿼리 출력을 사용하여 레일스 콘솔에서 작업을 실행하면 처음 몇 쿼리를 실행 한 후에 갑자기 시간이 1ms 미만에서 180ms로 증가하는 것을 알게되었습니다. 검색어.

나는 행동의 변화를보기 위해 innodb_buffer_pool_size를 줄 였지만 아무 것도 눈치 채지 못했습니다.

다음은 콘솔의 출력입니다 :

EmailCampaignReport::Open Columns (143.2ms) SHOW FIELDS FROM `email_campaign_report_opens` 
    SQL (0.3ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332330) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333333) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332661) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332326) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332665) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 336027) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333001) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 331983) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332668) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332316) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332325) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 331995) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 334007) 
    SQL (0.2ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333326) 
    SQL (0.1ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332998) 
    SQL (183.9ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 334673) 
    SQL (183.7ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 336751) 
    SQL (183.6ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333334) 
    SQL (186.3ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332663) 
    SQL (183.7ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332328) 
    SQL (186.3ms) SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332659) 

그 테이블의 CUSTOMER_ID 컬럼에 인덱스가 있습니다.

왜 이런 일이 벌어 질지에 대한 제안이 있습니까?

감사

+0

인덱스 스키마를 볼 수 있도록 테이블 스키마를 게시 할 수 있습니까? – UltimateBrent

답변

4

쿼리를 하나만 실행하면 어떨까요?

SELECT customer_id, count(*) AS count_all FROM `email_campaign_report_opens` GROUP BY customer_id; 

당신은 당신이 그들 모두가 다음 일괄 그것을 반환에 대해 걱정하는 많은 기록을 가지고 있지만, 당신이 정말로 모든 고객이 쿼리를 실행하려면 왜 난 그냥 이해하지 않는 경우.

+0

왜 그렇게 생각하지 않았습니까! 고마워. – johnnymire

+0

다행이 당신에게 효과적입니다. ActiveRecord에서 객체와 반복자를 사용하여 모든 작업을 수행하는 것은 쉽지만 때로는 약간의 SQL이 가장 좋습니다. –

0

이 앱뿐만 아니라 당신의 레일에서 발생합니까, 또는 콘솔에서 실행할 때 그냥 일이 무엇입니까? 또한 Aptana와 같은 클라이언트를 사용하고 있습니까? 아니면 이것을 쉘에서 실행하고 있습니까?

+0

이것은 쉘에서 실행되었으며 Rails 응용 프로그램에서도 발생합니다. – johnnymire

0

Rails의 버전은 무엇입니까? 버전과 Ruby/Rails 코드에 따라 사용하지 않고 많은 양의 데이터를 캐싱하고 잠시 후에 새로운 데이터를 가져 오기 전에 가비지 수집을 수행해야하므로 지연이 발생할 수 있습니다. 이것은 추측입니다.

+0

It 's Rails 버전 2.3.2 – johnnymire

0

counter cache을 연결에 추가하는 것이 좋지 않습니까? (읽기 : email_campaign_report_opens_countCustomer 모델에 추가 하시겠습니까?) 물론 마이그레이션하는 동안 카운터를 초기화해야하지만 실제로는 빠르며 고객 테이블을 걷는 동안 관련 테이블을 만질 필요조차 없습니다.

+0

좋습니다. 이것은 거의 내가했던 일이었고, 나는이 스크립트로 모든 카운트를 업데이트하는 고객 모델에 비슷한 카운트 필드를 가지고있다. 연결이 생성 될 때 카운터 캐시를 업데이트하는 것이 더 좋을 수도 있습니다. 초기 마이 그 레이션 중에 쿼리 속도 문제가 계속 발생하지만 적어도 한 번은 해제됩니다. – johnnymire