2010-06-28 4 views
0

나는 내 머리를 감쌀 수없는 매우 오래된 쿼리를 최적화하려고합니다. 제가 보관하고자하는 결과는 다른 고객이 관심을 보였던 방문자, 즉 방문자가보고있는 제품과 함께 구입 한 다른 것을 웹 상점에서 추천하고 싶다는 것입니다.고객이 나열된 제품과 함께 구입 한 제품에 대한 질문

서브 쿼리가 있지만, 은 매우입니다. 천천히, ~ 8000 000 행 ~ 15 초 걸립니다.

레이아웃은 사용자 바구니에있는 모든 제품을 wsBasket 테이블에 보관하고 basketid (다른 테이블은 멤버와 연결됨)으로 구분합니다.

이 예에서는 사용자가 productid 427과 함께 구입했지만 productid 427 자체를 나열하지 않은 가장 인기있는 제품을 모두 나열하려고합니다.

SELECT productid, SUM(quantity) AS qty 
FROM wsBasket 
WHERE basketid IN 
    (SELECT basketid 
    FROM wsBasket 
    WHERE productid=427) AND productid!=427 
GROUP by productid 
ORDER BY qty 
DESC LIMIT 0,4; 

어떤 도움을 많이 받으실 수 있습니다! 그들은 코멘트 필드에 적합하지 않은, 여기에 귀하의 의견들에 대한 덕분에 내 대답입니다 :이 모든 적어도 누군가에게 어떤 의미가 있습니다 :

 

UPDATE 1 바란다.

위의 쿼리에서 EXPLAIN을 사용하여 나는 플로팅을 얻었습니다. 참고, 나는 테이블에 인덱스가 없다 (기본 키는 id -field 제외). 나는 인덱스를 활용하고 쿼리를 수정하여 오른쪽 키에 인덱스를 넣고 싶다. 추가

+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+ 
| id | select_type  | table | type | possible_keys | key | key_len | ref | rows | Extra          | 
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+ 
| 1 | PRIMARY   | wsBasket | ALL | NULL   | NULL | NULL | NULL | 2821 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | wsBasket | ALL | NULL   | NULL | NULL | NULL | 2821 | Using where         | 
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+ 
+0

wsBasket 테이블에 어떤 인덱스가 있습니까? 쿼리에 EXPLAIN을 실행하면 무엇을 얻게됩니까? –

+0

인덱스는 어떻게 생깁니 까? 그 사실을 알면 쿼리 수정을보다 쉽게 ​​할 수 있습니다. 트릭을 수행 한 – MJB

답변

1

두 명백한 인덱스 : basketid에 하나 제품 ID에 두 번째 : 다음 쿼리를 다시 시도 해 새로운 인덱스는 주로 검색에 사용

+0

, 지금 쿼리에 ~ 0.124!:) 그리고 나는 조합 된 인덱스를 찾고 쿼리를 수정했다. 감사! 하위 쿼리를 피할 수있는 방법이 있습니까? – johan

+0

복합/복합 인덱스는이 테이블에 대한 다른 쿼리에 유용 할 수 있지만 더 많은 정보가 없으면 어떤 다른 쿼리 유형이 실행되는지는 알 수 없습니다. 그러나이 두 가지 간단한 인덱스가 도움이 될 것으로 생각됩니다. 응용 프로그램 코드의 다른 영역도 마찬가지입니다. –

+0

쿼리 수정에 대한 bobince의 응답 참조 –

0

두 필드를 사용하는 것을 볼 수에게 설명 이 쿼리에는 productid와 basketid가 있습니다.

productid가 427 인 레코드를 검색 할 때 데이터베이스는이 레코드를 찾을 수있는 단서가 없습니다. 일치하는 항목이 하나라도 발견되면 다른 일치하는 항목이 없으므로 전체 테이블, 잠재적으로 수천 개의 레코드를 조사해야한다는 것을 알지 못합니다.

색인은 정렬 된 별도의 파일이며 정렬하려는 필드 만 포함합니다. 따라서 색인을 생성하면 엄청난 시간을 절약 할 수 있습니다!

1

productidbasketid에 적합한 색인이 있는지 확인하는 것 외에 특히 MySQL에서 하위 쿼리가 아닌 간단한 조인으로 쿼리를 구성하는 것이 좋습니다. 부질 방법 끔찍한를 위해 성능 DEPENDENT SUBQUERY 아웃 스팻 반면 나를 위해

SELECT b1.productid, SUM(b1.quantity) AS qty 
FROM wsBasket AS b0 
JOIN wsBasket AS b1 ON b1.basketid=b0.basketid 
WHERE b0.productid=427 AND b1.productid<>427 
GROUP BY b1.productid 
ORDER BY qty DESC 
LIMIT 4 

는 가능성이 유사성 세트에서, 상기 두 개의 출력 EXPLAINselect_type: SIMPLE 행 결과 조인. 결과적으로 조인은 훨씬 빠르게 진행되었습니다.

+0

+1 –