2009-07-24 2 views
1

이 쿼리를 어떻게 향상시킬 수 있습니까? 내 소셜 네트워크로 DB는 더 큰MySQL 데이터베이스가 커지면 어떤 옵션이 있습니까

이 쿼리 2.1231 초 걸렸다지고 여기 나에게 내 모든 옵션을 알려주세요

SELECT friend_friend.friendid, friend_reg_user.disp_name, friend_reg_user.pic_url, friend_reg_user.online 
FROM friend_friend 
INNER JOIN friend_reg_user ON friend_friend.friendid = friend_reg_user.auto_id 
WHERE userid =1 
AND friend_friend.status =1 
ORDER BY autoid DESC 
LIMIT 59535 , 15 


##################################################################################################################################### 
# id # select_type # table   # type # possible_keys # key  # key_len # ref      # rows # Extra  # 
##################################################################################################################################### 
# 1 # SIMPLE  # friend_friend # ref  # userid  # userid # 5  # const     # 59843 # Using where# 
# 1 # SIMPLE  # friend_reg_user # eq_ref # PRIMARY  # PRIMARY # 4  # friend_friend.friendid # 1  #   # 
##################################################################################################################################### 

이 테이블은 만 또는 200 만 개 행을 말할 때 내 옵션은 무엇입니까 큰? 이 테이블은 사용자가 누구인지를 결정하는 데 사용됩니다.

답변

2

저는 데이터베이스에서 8 백만 개의 레코드로 작업하는 프로그래머를 알고 있으며, 실제로 속도를 많이 변경하지 않습니다. 올바른 인덱스를 만들고 효율적인 방식으로 데이터를 가져 오는 것입니다. (관계에 대한 숫자 ID는 실제로 유용합니다.)

또한 쿼리는 실제로 대부분 베어 본입니다. 너무 화려하지는 않습니다. 서버 대기 시간 일 수도 있습니다.

+0

그래, 나는 그것이 될 수있는만큼 많이 최적화되었다고 생각했는데, 모든 올바른 색인과 물건들이 있지만 2 초 이상은 느리다. 이것은 아마 localhost에서 실행 되었기 때문에 느린 이유 일 수 있습니다. – JasonDavis

+0

8 백만 레코드가 실제로 그렇게 많은 것은 아닙니다 ... 당신이 10 억에 도달하면 어떻게되는지보십시오. – MarkR

+0

인덱스가 150 만 개 이상인 myisam 테이블을 사용하면 인덱스를 효율적으로 사용할 수있는 쿼리를 수행 할 때 quieries가 여전히 탁월합니다. – nos

2

어쩌면 나는 귀하의 스키마를 이해하지 못 하겠지만 실제로는 LEFT JOIN이 필요합니까? INNER JOIN을 사용할 수 없습니까?

(공연 횟수가 적을수록 좋을지도 모른다고 들었지만, 한 사람의 친구를 원한다면 친구가 될 수도 있습니다. 아니, "연결"테이블에 항목이, "링크"와, 너무)

또한

, 당신이 사용하는 필드에 인덱스가 만들어 : 조건

  • 을 (중 "여기서" 또는 "참여"); 여기 괜찮을 것 같니?
  • 정렬 용; 자존심에는 색인이 있습니까?

MySQL은 일부 응용 프로그램에서 실제로 큰 테이블과 함께 사용되며 인덱스/구성이 정상이면 매우 빠르게 응답 할 수 있습니다. 그래서, 우리가 할 수있는 일이 분명히 있습니다 .-))

사이드 노드로 : 당신은 테이블의 이름으로 거의 모든 필드의 이름을 접두사로 붙이게됩니다 (필자는 필드의 이름이 중복되어 있기 때문입니다) ; 왜 항상합니까? 쿼리를 좀 더 쉽게 이해할 수 있습니다 :-)

+0

안녕하세요. 실제로 게시 된 시간은 2.1231 초였습니다. 내부 조인 여기에서 업데이트하는 것을 잊어 버렸습니다. 왼쪽 가입 시간은 2.4231 정도 였으므로 사소한 개선이있었습니다. 네, 모든 오른쪽 열에 인덱스가 있습니다. 그리고 정렬 된 자 동체가 기본 키이므로 인덱스를 가질 수 없습니까? 기본 키가 색인이라는 뜻인가요? 나는 그것이 최선이 될 수 있다고 생각하지만, 2 초 내내 오히려 느리다. = ( – JasonDavis

+0

ergh, 너무 나쁜 모든 필요한 인덱스가 있다면 :-((그리고 옙, PK 역시 인덱스이다.) 다음 단계는 비정규 화 (http://en.wikipedia.org/wiki/Denormalization) 또는 Sharding (http://en.wikipedia.org/wiki/Sharding) 일 수 있습니다 ...하지만 좀 더 어렵게 만듭니다 ... –

1

WHERE 절의 열이 인덱스 인만큼 괜찮을 것입니다. 나는 많은 테스트 데이터를 생성하고 벤치 마크를 실행할 것이다.

더욱 중요하게는 MySQL's EXPLAIN 구문을 익히십시오. 쿼리에서 실제로 사용되는 행의 수를 결정하는 데 도움이되며 쿼리 및 테이블 인덱스를 최적화하는 데 유용한 도구입니다.

0

느린 원인을 찾아야합니다.

데이터베이스가 메모리에 저장되어 있습니까? 그렇지 않다면 더 많은 것을 얻으십시오 - 아니, 정말로. 디스크가 어떻게 보일지라도 디스크는 느립니다.

만약 당신의 쿼리가 절대적으로 디스크를 사용해야한다면 (합당한 메모리를 얻기에는 너무 큰 데이터베이스, 100G +라고 말함), 필요한 IO 작업의 수를 최소화해야합니다.

사실 이것은 특정 양의 비정규 화를 의미합니다 (실제로 참여해야합니까?xref 테이블에 필요한 모든 필드를 (복사본으로) 저장할 수 없습니까?), 커버하는 인덱스를 현명하게 사용 할 수 있습니까?

InnoDB (여기서 Innodb을 사용한다고 가정 함)에서는 기본 키가 클러스터링됩니다. 즉, 기본 키를 사용하는 쿼리는 각 행에 대해 개별적으로 IO를 수행 할 필요가 없기 때문에 (인덱스가 동일한 페이지에 데이터와 함께 저장되기 때문에) 다른 인덱스보다 IO가 적습니다. 보조 색인에 필요합니다.

기본 원칙은 다음과 같습니다

  1. 그것이
  2. 변화를 확인 일으키는
  3. 무엇을 진단 비 프로덕션 환경에서 생산 사양 하드웨어에서 데이터의 생산 수준을 사용하여 문제를 재현하는 수정 가능하다고 생각할 수도 있습니다.
  4. 동일한 프로덕션 - 스펙 비 프로덕션 환경을 사용하여 다시 측정하여 수정 프로그램의 성능을 검증하십시오. 이 문제를 해결하기에 충분한 성능을 가지고 때까지
  5. 반복

그리고 성공하면, 당신은 다음 무엇이든 정상적인 품질 보증 절차를 수행 할 수 있습니다 (예를 들면 회귀 테스트 등) (당신의 고객을 등 달래기 위해) 해제하는 것입니다 변화.

변경 사항에 따라 중요한 데이터 마이그레이션이 필요하므로 배포하기에 큰 어려움이 따릅니다 (데이터 테이블의 10Tb 스키마 변경 필요).

관련 문제