2010-02-21 2 views
2

내 WordPress 사이트에서 사용자가 게시물 목록에서 멀리 페이지를 이동하면 쿼리가 몇 초가 걸립니다. 나는 이것을 내리고 싶다. 다음은 실행중인 쿼리입니다.이전 게시물에 대한 WordPress SQL 쿼리 최적화 목록

SELECT SQL_CALC_FOUND_ROWS wp_posts.* 
FROM wp_posts 
WHERE 1=1 
    AND wp_posts.post_type = 'post' 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
ORDER BY wp_posts.post_date DESC 
LIMIT 846, 47 

테이블에 약 160,000 개의 행이 있습니다. 다음은 스키마의 단순화 된 버전입니다 :

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE wp_posts ref type_status_date  type_status_date  62 const 41519 Using where; Using filesort 

적으로는, 내가이 filesort 제거 싶습니다

CREATE TABLE `wp_posts` (
    `ID` bigint(20) unsigned NOT NULL auto_increment, 
    `post_date` datetime NOT NULL default '0000-00-00 00:00:00', 
    `post_status` varchar(20) NOT NULL default 'publish', 
    `post_type` varchar(20) NOT NULL default 'post', 
    PRIMARY KEY (`ID`), 
    KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

이것은 EXPLAIN 쿼리의 결과입니다. 어떤 팁?

+0

에 매겨진 디스플레이를 최적화에

더 많은 정보 ...? –

+0

인덱스는 질문의 테이블 스키마에 있습니다. ID에는 기본 키가 있고 복합 색인에는 'post_type','post_status','post_date','ID'가 있습니다. –

답변

1

주문 열 (post_date)에 색인을 작성해야합니다. 색인없이 모든 160k 행을 가져오고, filesorted 한 다음 대부분을 버립니다.

memcache 또는 유사한 캐시 엔진에 결과 창을 저장하고보다 적극적인 캐싱을보고 싶을 수도 있습니다.당신이 자리에 있습니까 어떤 인덱스 http://www.mysqlperformanceblog.com/2008/09/24/four-ways-to-optimize-paginated-displays/

+0

흠, 그건 예상치 못한 일입니다. 순서 열에 만 인덱스를 추가하고 "USE INDEX (post_date_idx)"를 사용하여 MySQL에 사용하도록 지시하면 성능이 훨씬 더 좋아집니다. 감사! –

1

post_type, post_statuspost_date에 대한 색인이 있어야합니다.

160k 행은 문제가되지 않습니다.

+0

해당 색인이 이미 있습니다. 테이블 스키마를 참조하십시오. "문제가되지 않는다"는 것은 상대적입니다. 현재 질의는 2 초 정도 걸리고 파일롯을 사용합니다. 속도를 높이고 결국 파일을 없애고 싶습니다. –

-1

음, 이것은 단지 추측이지만, 어쨌든 post_date을 다중 열 인덱스에 넣으려고합니다. 그런 다음 색인을 날짜순으로 정렬해야하며 결과 정렬은 색인을 순회하여 수행 할 수 있습니다. MySQL에서 실제로 작동하는 경우 시도하지 않았습니다.

0

OR을 사용할 때 확실한 색인이 양쪽에 사용됩니다.

SELECT SQL_CALC_FOUND_ROWS wp_posts.* # change this to select only columns you need 
FROM wp_posts 
WHERE (wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish') or (wp_posts.post_type = 'post' OR wp_posts.post_status = 'private') 
ORDER BY wp_posts.post_date DESC LIMIT 846, 47 

또한 post_statuspost_type이 열거 될 수 있도록 것입니다. 또한 주문 열 (post_date)에 별도의 색인을 추가하십시오. 다중 색인의 경우와 같이 왼쪽의 첫 번째 열만 개별 색인으로 사용할 수 있습니다.

-1

보기는 http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql입니다. 권고가 기본적으로

  • 절하여 어디 위해 모두를 사용할 수있는 적절한 인덱스가 아래로 끓인다.
  • 행을 표시하기 위해 COUNT() (또는 그 사촌 SQL_CALC_FOUND ROWS)을 사용하지 마십시오 (몇 개의 UI 변경 사항 또는 집계가 필요한 경우 별도의 입력란에 표시됨).
  • 이가 아주 똑똑 달성하기 위해 LIMIT M, N 사용 LIMIT N (방법을 사용하지 마십시오 : 예를 들면 당신은으로 분류 게시물이있는 경우 DESC는, 당신은보다 기본 키 적은을 추가하여 다음 페이지를 얻을 수 있습니다 키 현재 페이지의 마지막 요소).

편집 : 첫 번째 포인트는 피터 랭의 대답에 덮여 있지만, 호출기 다른 열을 정렬 할 수 있다면, 인덱스가 충분하지 않을 수 있음을 유의하시기 바랍니다있다.

+0

프레젠테이션을 한 번 연결하면 실제로 "사용자가 아카이브에 깊이 들어가게하지 마라 - 위키피디아의 인터넷 중독 페이지로 연결"하십시오. 기본적으로 '제한'의 문제를 전혀 해결하지 않고 사용자 경험을 희생함으로써 해결합니다. – raveren

+0

@Raveren : 링크 된 프리젠 테이션에는 총 26 개의 슬라이드가 있습니다. 처음 9 개는 문제를 자세히 설명합니다. 인용하고있는 10 번째 버전은 * 간단한 솔루션 *이 페이징을 허용하지 않는다고 말합니다 (그리고 사용자를 위키 페이지로 리디렉션 할 수있는 '혀 - 뺨 (tongue-in-cheek)'). 다음 16 가지 세부 솔루션 이러한 주제가 주제가 맞지 않거나 올바르지 않습니까? 그렇다면 알려 주시기 바랍니다. –