당신이 읽을 내용은 다소 해킹이므로 집에서 시도하지 마십시오!
SQL에서 일반적으로 귀하의 질문에 대한 답변은 NO 이지만 GROUP BY
( @bluefeet에 의해 언급 된 ) 완화 모드로 인해 MySQL 의 대답은 예 입니다.
(post_status, post_type, post_author, post_date)에 BTREE 인덱스가 있다고 가정하십시오. 후드 아래의 인덱스는 어떻게 보입니까?
(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-31') (post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-10-01') (post_status = 'publish', post_type = ' post ', post_author ='사용자 B ', post_date ='2012-12-01 ')
즉, 데이터는 모든 필드를 기준으로 오름차순으로 정렬됩니다.
GROUP BY
기본적으로 작업을 수행 하면 그룹화 필드 ( post_author
, 우리의 경우 post_status, post_type이 WHERE
절에 필요함)별로 데이터를 정렬하고 일치하는 인덱스가 있으면 첫 번째 레코드마다 오름차순으로 데이터를 가져옵니다. 즉, 쿼리는 다음을 가져옵니다 (각 사용자의 첫 번째 게시물).
(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-10-01')
그러나 GROUP BY
MySQL에서는 순서를 명시 적으로 지정할 수 있습니다. 그리고 post_user
내림차순으로 요청하면 색인이 반대 순서로 진행되어 실제로 마지막 인 각 그룹의 첫 번째 레코드를 계속 사용합니다.
그건
...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
우리에게 줄 것이다
(post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-31')
이제 post_date로 그룹화 결과를 주문하면 원하는 데이터를 얻을 수 있습니다.
SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
ORDER BY wp_posts.post_date DESC;
NB :
이것은이 특정 쿼리에 권장하지 않습니다. 이 경우 @bluefeet가 제안한 약간 수정 된 버전을 사용 합니다. 그러나이 기술은 매우 유용 할 수 있습니다. 내 대답을 여기에서보십시오 : 각 그룹의 마지막 레코드 검색
함정 : 접근 방식의 단점은
- 쿼리 결과는 SQL의 정신에 위배되는 인덱스에 따라 다릅니다 (인덱스는 쿼리 속도를 높여야합니다).
- 인덱스는 쿼리에 미치는 영향에 대해 아무것도 알지 못합니다 (나중에 누군가 다른 사람이 인덱스를 너무 많이 소비하고 인덱스를 변경하여 성능뿐만 아니라 쿼리 결과를 깨뜨릴 수 있음)
- 쿼리의 작동 방식을 이해하지 못하는 경우 한 달 안에 설명을 잊어 버릴 수 있으며 쿼리가 사용자와 동료를 혼란스럽게 할 것입니다.
장점은 어려운 경우의 성능입니다. 이 경우 정렬과 관련된 데이터 양 때문에 모든 쿼리가 @bluefeet의 쿼리와 동일해야합니다 (모든 데이터는 임시 테이블에로드 된 후 정렬됩니다. btw, 쿼리에는 (post_status, post_type, post_author, post_date)
인덱스도 필요함 ). .
내가 제안하는 것 :
내가 말했듯이, 이러한 쿼리는 MySQL 낭비 시간을 잠재적으로 대량의 데이터를 임시 테이블에서 정렬하게합니다. 페이징이 필요한 경우 (즉, LIMIT 관련) 대부분의 데이터가 폐기됩니다. 내가 할 일은 정렬 된 데이터의 양을 최소화하는 것입니다. 즉, 하위 쿼리에서 최소 데이터를 정렬하고 제한 한 다음 전체 테이블로 다시 조인합니다.
SELECT *
FROM wp_posts
INNER JOIN
(
SELECT max(post_date) post_date, post_author
FROM wp_posts
WHERE post_status='publish' AND post_type='post'
GROUP BY post_author
ORDER BY post_date DESC
-- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';
위에서 설명한 접근 방식을 사용하는 동일한 쿼리 :
SELECT *
FROM (
SELECT post_id
FROM wp_posts
WHERE post_status='publish' AND post_type='post'
GROUP BY post_author DESC
ORDER BY post_date DESC
-- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);
에 자신의 실행 계획과 그 모든 쿼리 SQLFiddle .
post_author
와post_date
고유 행을 얻을하는 것만으로는 충분하지, 그래서 당 고유 한 행을 얻기 위해 더이 있어야한다post_author