wp_options 테이블에 대한 느린 쿼리


16

WP 기반 사이트의 느린 쿼리 로그를 추적하고 ( long_query_time 의 기본값 이 10으로 설정 됨) 다음 쿼리가 종종 기록되는 것을 알았습니다.

# User@Host: root[root] @ localhost []
# Query_time: 0  Lock_time: 0  Rows_sent: 394  Rows_examined: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

그런 작은 테이블을 실행하는 데 많은 시간이 걸리는 방법을 이해하지 못합니다. 이것은 다른 문제의 증상 일 뿐입니 까? (전용 VM에서 Moodle, phpbb 및 WP를 현재 실행 중).

답변:


16

업데이트 : 쿼리가 기록되는 이유 는 인덱스를 사용하지 않기 때문 입니다. 쿼리 시간은 0입니다. 즉 실제로 실제로 실행됩니다. "log-queries-not-using-indexes"옵션을 기록하지 않으려면 설정을 해제 할 수 있습니다.

wp_options 테이블에는 자동로드에 대한 인덱스가 없으므로 쿼리는 전체 테이블 스캔을 수행합니다. 일반적으로 테이블이 너무 커서는 안되므로 문제가되지 않지만 귀하의 경우에는 어떻게 든 일어 났을 것입니다.

색인을 추가하면 문제가 해결 될 수 있지만 TheDeadMedic이 주석에서 지적했듯이 자동로드 값이 yes 또는 yes와 no 사이에 균등하게 분배되는 경우에는 그렇지 않을 수 있습니다.

먼저이 쿼리를 통해 분포가 어떻게 보이는지 확인하십시오.

SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;

대다수가 '아니오'로 설정된 경우 자동로드에 색인을 추가하여 지금 문제를 해결할 수 있습니다.

ALTER TABLE wp_options ADD INDEX (`autoload`);

그러나 해당 테이블이 너무 큰 이유를 알아볼 수 있습니다. 비린내가 뭔가 잘못 작성된 플러그인 일 수 있습니다.


2
이 경우 인덱스가 카디널리티에 대한이 기사를 확인하는 데 도움 되지 않을 것 입니다.
TheDeadMedic

대부분의 옵션이 자동로드로 설정되어 있는지 여부에 따라 다릅니다. 나는 생각하지 않지만 테이블에서 어쨌든 너무 커져서 비린내가 일어나지 않아야한다고 생각합니다.
Vinay Pai

1
나는 값의 분포를 확인하는 것에 대해 약간 추가하기 위해 답변으로 업데이트했습니다.
Vinay Pai

1
방금 의견을 보았고 내 대답이 완전히 잘못되었다는 것을 깨달았습니다. 쿼리는 실제로 느리지 않습니다 ... 인덱스를 사용하지 않기 때문에 느린 쿼리 로그에 기록됩니다.
Vinay Pai

1
이 질문과 답변 덕분에 wp_options 테이블에 90k 개의 항목이 있으며 그 중 88.5k가 자동로드 false로 설정되어 있음을 알았습니다. 나머지는 모두 플러그인에 의해 추가 된 "일시적인"항목이었습니다 (캐싱을 위해?). 자동로드 열에 인덱스를 추가하면 mySql로드가 평균 89 %에서 2.5 %로 즉시 떨어졌습니다. 모니터링 에이전트는 내 사이트의 응답 시간이 1900ms에서 500ms로 감소했음을 보여줍니다. 이것은 나를위한 게임 체인저였습니다.
Mordred

5

며칠 전에 내 서버에서 실행되는 mytop에서 언급 한 쿼리를 우연히 발견했습니다. 실제로 각 쿼리마다 상당한 시간 (약 10 초)이 걸렸습니다! 따라서 wp_options가 문제의 크기로 커지는 실제 상황이 있습니다. 내 경우에는 캐싱 플러그인이 의심됩니다. Cachifywp_options 를 부 풀릴 책임이 .

이 특정 wp_options의 데이터 :

5,309 rows
130MB of data

해결책으로 Vinay Pai가 게시 한 솔루션과 비슷한 색인을 추가하여 문제를 완벽하게 해결했습니다.


1

내 wp_options 테이블에는 약 235 행의 데이터 만있었습니다. 테이블 인덱싱을 시도했지만 도움이되지 않았습니다.

약 150 개의 임시 옵션이 테이블에 삽입되었지만 자동으로 삭제되지는 않았습니다.

관련 여부는 알지 못하지만 /var/log/apache2/access.log 파일을 살펴본 결과 여러 개의 (아마도 손상된) Amazon Web Services 서버 (54로 시작하는 IP 주소)가 발견되었습니다. XXX and 32.XXX)는 /~web-root-dir/xmlrpc.php를 악용하려고 시도했습니다.

문제를 해결 한 후 "transient"가 포함 된 옵션 이름에 대해 wp_options 테이블을 쿼리했습니다.

wp_options에서 *를 선택하십시오. 여기서 option_name은 '% transient %' 와 같습니다 .

이 쿼리에서 반환 된 필드 중 하나는 데이터 유형이 LONGTEXT 인 'option_value'입니다. mySQL 문서에 따르면 LONGTEXT 필드 (각 행)는 최대 4 기가 바이트의 데이터를 보유 할 수 있습니다.

쿼리를 실행할 때 일부 행 ( "일시적"을 포함하는 행과 작업했음을 기억하십시오)이 방대했습니다. option_value 필드에있는 데이터의 양. 결과를 살펴보면, cron주기 동안 실행될 것이라는 희망으로 wp-cron 프로세스에 명령을 삽입하려는 시도가 어떻게되는지 보았습니다.

내 해결책은 모든 "과도"행을 삭제하는 것이 었습니다. "일시적인"행이 자동으로 다시 채워 지므로 (서버가있는 경우) 서버를 손상시키지 않습니다.

이 작업을 수행 한 후 서버가 다시 응답했습니다.

다음 행을 삭제하기위한 쿼리 :

wp_options에서 삭제합니다. 여기서 option_name은 '% transient %' .

방화벽에 AWS IP 주소 / 8 수퍼 블록도 추가했습니다 (-:


네. "40 초의로드 시간"으로 인해 20,000 개의 wp_option 레코드가 있고 매 페이지마다 많은 데이터가로드되는 것을 발견 할 때까지 어려움을 겪고있었습니다. 사이트를 상당히 빠르게 제거했습니다.
JasonGenX
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.