10

나는 NewsStories 테이블을 가지고 있는데, 관련 테이블과 합류하게된다. 각 뉴스 기사에는 여러 개의 이미지, 카테고리 및 주소가있을 수 있습니다. 따라서 쿼리는 본질적으로 다음과 같습니다.

SELECT * FROM NewStories 

LEFT JOIN Images ON Newstories.id=Images.story_id

LEFT JOIN Categories ON NewsStories.id=Categories.story_id

LEFT JOIN Addresses ON NewsStories.id=Addresses.story_id

WHERE ...

일반적으로 이야기 당 몇 개의 이미지와 주소 및 1 개 또는 2 개의 카테고리가 있습니다. NewsStories 테이블에는 약 10,000 개의 기사가 있습니다.

문제는 성능이 다소 느리다는 것입니다 (15-20 초 정도의 차이가 있지만 매우 다양하고 때로는 5 초로 떨어집니다).

나는 속도를 높이기 위해 질의를 구성하는 더 좋은 방법이 있는지 궁금했다. (나는 SQL에 대해 아주 익숙하다.)

특히 주어진 스토리에 대한 행의 수에 이미지 수와 주소 수와 카테고리 수를 곱한 값을 곱하면 꽤 낭비적인 것처럼 보입니다.

필자는 뉴스 스토리의 속성을 프론트 엔드에서 조작 할 수있는 단일 객체로 재구성하려고합니다.

여기에 설명이 있습니다 (서식이 올바르게 나오지 않으면 사과하십시오). 나는 "Where using"이라면 나는 Addresses를 적절하게 색인하지 않을 것이라고 추측하고있다. 그 맞습니까?

id  select_type table   type    possible_keys   key key_len ref rows    Extra

1   SIMPLE  Addresses   ALL NULL    NULL    NULL    NULL    6640    Using where

1   SIMPLE  NewsStories eq_ref  PRIMARY PRIMARY 767 NewsStories.Addresses.story_id 1    Using where

1   SIMPLE  Images  ref PRIMARY PRIMARY 767 NewsStories.NewsStories.id  1   Using index

1   SIMPLE  Categories  ref PRIMARY PRIMARY 767 NewsStories.NewStories.id   1


  • id select_type 테이블 유형 possible_keys 키 key_len ref 행 Extra 1 SIMPLE 주소 ALL NULL NULL NULL NULL 6640 사용 위치 1 SIMPLE NewsStories eq_ref PRIMARY PRIMARY 767 NewsStories.Addresses.story_id 1 사용 위치 1 SIMPLE 이미지 참조 PRIMARY PRIMARY 767 NewsStories.NewsStories.id 1 색인 1 간단한 범주 ref 기본 PRIMARY 767 NewsStories.NewStories.id 1 - Vijay Boyapati
  • 이 질문에 대한 내 대답을 참조하십시오 :stackoverflow.com/questions/6771975/sql-joining-6-tables/… - yper-crazyhat-cubeᵀᴹ

2 답변


6

  • WHERE 문과 ON 조건에있는 필드에 인덱스가 있는지 확인하고 기본 키는 기본적으로 인덱싱되지만 필요하면 수동으로 인덱스를 만들 수도 있습니다.

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name       [index_type]       ON tbl_name (index_col_name, ...)       [index_type]

index_col_name :       col_name [(길이)] [ASC | DESC]

index_type :       USING {BTREE | 해시시}

  • 모든 테이블에서 모든 열을 선택해야하는지 확인하십시오. 그렇지 않은 경우 필요한 열만 선택했는지 확인하십시오.고르다*

  • LEFT JOINS가 실제로 필요한지 다시 한 번 확인하고, 없으면 INNER JOIN을 사용하십시오.

  • 쿼리를 조정 한 후에도 성능이 여전히 문제가된다면 스키마를 비정규 화하여 조인을 제거하십시오

  • 또한 sphinxsearch 및 memcached와 같은 캐싱 응용 프로그램을 사용하여 데이터베이스의로드를 줄이는 것이 좋습니다.

  • 조인이 실제 테이블이 아닌 뷰에 있는지 확인하십시오.

참고 문헌 :

http://www.sphinxsearch.com

http://dev.mysql.com/doc/refman/5.0/en/create-index.html


  • 고마워. 후속 질문 : 왼쪽 가입의 ON에 나타나는 열을 색인화해야하는 이유는 이해하지만 어디에서 열을 색인화해야하는지 이해하지 못합니다. 이러한 열은 필터링 할 수있는 뉴스 기사의 다양한 속성이지만 색인 생성에는 많은 가치가 없습니다. 조인에서 사용되지 않는 컬럼을 인덱싱하려면 성능이 실제로 향상됩니까? 그렇다면 왜? - Vijay Boyapati
  • 네, 이것은 mysql 레퍼런스 가이드에 명시 적으로 언급되어 있습니다. "MySQL은 이러한 연산을 위해 인덱스를 사용한다 : WHERE 절과 일치하는 행을 신속하게 찾는다."dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html - Mark Basmayor
  • 우수한. 포인터 주셔서 감사. - Vijay Boyapati
  • 에 대한 스마트 답변Check none of your joins are to views rather than actual tables. (및) - NullPointer

0

테이블의 색인이 올바르게 작성되었는지 확인하십시오. 데이터를 선택하는 데 사용하는 모든 열에 대해 인덱스가 있어야합니다. 그렇지 않으면 MySQL은 테이블의 모든 행을 통과하게됩니다.

검색어 설명 시도 (EXPLAIN SELECT * FROM ...etc)를 사용하여 MySQL이 테이블을 내부적으로 처리하는 방법을 확인하십시오. 추가 도움을 받으려면 질문에 결과를 붙여 넣으십시오.


  • id select_type 테이블 유형 possible_keys 키 key_len 참조 행 추가 1 간단한 주소 ALL NULL NULL NULL NULL 6640 사용 위치 1 간단한 뉴스 스토리 eq_ref PRIMARY PRIMARY 767 NewsStories.Addresses.story_id 1 1 SIMPLE 이미지 참조 PRIMARY PRIMARY 767 NewsStories .NewsStories.id 1 색인 사용하기 1 간단한 카테고리 ref primary PRIMARY 767 NewsStories.NewStories.id 1 - Vijay Boyapati

연결된 질문


관련된 질문

최근 질문