친구가 가장 많이 본 페이지를 표시 할 수있는 기능을 제공하려고합니다. 내 친구 테이블에는 5.7M 행이 있고보기 테이블에는 5.3M 행이 있습니다. 지금은이 두 테이블에 대한 쿼리를 실행하고 가장 많이 본 페이지 ID를 사람의 친구가 찾고자합니다. 여기 두 개의 큰 테이블에서 간단한 쿼리 최적화
내가 지금 가지고있는 쿼리의 :SELECT page_id
FROM `views` INNER JOIN `friendships` ON friendships.receiver_id = views.user_id
WHERE (`friendships`.`creator_id` = 143416)
GROUP BY page_id
ORDER BY count(views.user_id) desc
LIMIT 20
을 그리고 여기에 외모를 설명하는 방법은 다음과 같습니다
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | friendships | ref | PRIMARY,index_friendships_on_creator_id | index_friendships_on_creator_id | 4 | const | 271 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | views | ref | PRIMARY | PRIMARY | 4 | friendships.receiver_id | 11 | Using index |
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
견해 테이블 (USER_ID, 페이지 ID)의 기본 키가를, 그리고 당신 이것이 사용되고있는 것을 볼 수 있습니다. 우정 테이블에는 (receiver_id, creator_id)의 기본 키와 (creator_id)의 보조 색인이 있습니다.
group by 및 limit없이이 쿼리를 실행하면이 특정 사용자에 대해 약 25,000 개의 행이 발생합니다. 이는 일반적입니다.
가장 최근의 실제 실행에서이 쿼리는 7 초가 지나서 실행되었는데, 이는 웹 앱의 적절한 응답을하기에는 너무 길다.
두 번째 색인을 (creator_id, receiver_id)로 조정해야하는지 궁금한 점이 하나 있습니다. 나는 그것이 성능 향상을 많이 줄 것이라고 확신하지 못합니다. 나는이 질문에 대한 대답에 따라 오늘 그것을 시도 할 것입니다.
번개를 빨리 줄이기 위해 쿼리를 다시 작성할 수있는 방법을 볼 수 있습니까?
업데이트 : 더 많은 테스트를해야하지만 DB에서 그룹화 및 정렬을 수행하지 않으면 내 불쾌한 쿼리가 더 잘 나타납니다.하지만 나중에 루비에서 수행하십시오. 전반적인 시간은 훨씬 짧습니다 - 약 80 % 정도는 보인다. 어쩌면 내 초기 테스트에 결함이있는 것 같았지만 이는 분명히 더 많은 조사가 필요합니다. 그것이 사실이라면 - wtf가 MySQL에서하고있는 것입니까?
두 표를 설명해 주시겠습니까? –
두 테이블 모두 거의 볼 수 있습니다. Friendship은 receiver_id (int)와 creator_id (int)를 가지고 있고, 다른 자동 증가 ID 필드를 보조 키로 가지고 있습니다 (레일스 + memcached는 적합하지 않습니다). 뷰에는 user_id (int), page_id (bigint) 및 자동 증가 ID 필드가 있습니다. –
friendships.receiver_id 및 views.user_id가 모두 색인 생성되어 있다고 가정합니다. 그리고 page_id에 대한 bigint? int는 최대 43 억 개의 값을 저장할 수 있습니다 (성능 병목 현상에 대한 브레인 스토밍). –