2010-03-09 3 views
0

제품이있는 상당히 큰 테이블을 가진 MySQL 데이터베이스가 있습니다. 각각은 고유 id 및 categoryId 필드를 가지며 카테고리 ID는이 제품에 속합니다. 지금과 같은 특정 카테고리의 제품을 꺼내서 쿼리가 : 물론IN 연산자로 MySQL 쿼리 최적화

SELECT * FROM products WHERE categoryId IN (1, 2, 3, 4, 5, 34, 6, 7, 8, 9, 10, 11, 12) 

을 와서 WHERE 정렬하지만이 일에 절 및 ORDER. 이 제품이 250k이고 방문수가 하루에 100k를 초과한다고 가정 해 보겠습니다. 테이블 slow_log 이러한 조건에서 큰 생성 시간이 쿼리의 등록 된 무게.

주어진 문제를 최적화하는 방법에 대한 아이디어가 있습니까?

테이블 엔진은 MyISAM입니다.

+0

'categoryId'에 대한 색인이 있습니까? – DanMan

답변

2

categoryId의 인덱스는이 경우 도움이되지 않습니다. IN (...) 쿼리는 인덱스 검색 대신 시퀀스 검색을 생성합니다.

먼저 여러 범주 선택을 제거하기 위해 시스템을 다시 설계하고 적절하지 않은 경우 쿼리 결과를 캐싱하는 것이 좋습니다.

예를 들어, items_category_groups (hash, item_id) 도우미 테이블을 만들고 여러 카테고리의 클라이언트 쿼리가 조합 ID를 해시하고이 테이블을 조회 한 후에 만들 수 있습니다. 발견되지 않으면 비싼 쿼리를 작성하고이 테이블을 채우십시오. 발견되면,이 테이블을 결합하는 저렴한 쿼리를 만드십시오. memcached와 같은 다른 캐싱 도구도 작동합니다.

+0

좋은 생각이지만이 쿼리는 주어진 카테고리와 그 하위 카테고리 (이 카테고리의 전체 브랜치)에 대한 제품을 추출하기 위해 사용됩니다. –

+0

캐시 크기가 커지 더라도 캐싱 만 볼 수있는 유일한 방법입니다 (250k * 카운트 범주 조합의), 그래서 나는 DB에, memcache 또는 뭔가 저장하지 것입니다. – Andrey

+0

ONE 카테고리 (및 하위 카테고리)에서 제품을 가져 오려면 도우미 테이블 (category_id, item_id)을 만들고 하위 카테고리를 포함한 모든 category_id-item_id 쌍으로 항목을 채울 수 있습니다. 이 테이블은 그다지 크지 않을 것입니다 (예 : 네이밍 레벨이 4 인 경우 두 개의 int 행 카테고리가 1m * 개 이상 포함되지 않음). 그런 다음 인덱스를 사용하여 단일 쿼리를 사용하여 제품을 가져옵니다. – Andrey