매우 간단한 SELECT 쿼리에서 MySQL의 속도가 매우 느림


10

가상 머신에서 InnoDB 엔진을 사용하여 MySQL 5.5 데이터베이스에 데이터를 저장하는 간단한 웹 애플리케이션이 실행 중입니다. 약 3 년 동안 모든 것이 잘 작동했지만 갑자기 속도가 매우 느려졌습니다.

예를 들어 주소를 보유한 매우 간단한 테이블이 있습니다.

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

이 테이블에는 약 800 개의 항목이 있지만 실제로는 그렇지 않습니다. 그러나 쿼리 실행

SELECT * FROM addresses

테스트 목적으로는 결코 끝나지 않는 것 같습니다. 서버 자체의 mysql CLI로 이것을 확인했습니다. 테이블의 일부 행을 출력 한 다음 다음 행을 출력 할 때까지 매우 오래 기다립니다.

따라서 데이터 전송 단계에서 문제가 될 수 있지만 확실하지 않습니다.

VM에는 2GB의 RAM이 있으며 320MB 만 사용됩니다. CPU도 1 ~ 2 %로 매우 낮습니다. mytop은 서버를 차단하는 다른 쿼리를 표시하지 않습니다. IT 관리자는 하드웨어 측면에서 아무것도 변경하지 않았다고 말했다.

데이터베이스 서버를 다시 시작하고 가상 컴퓨터를 다시 시작하는 등의 작업을 이미 시도했습니다. 아무것도 도와주지 않았다.

편집하다:

EXPLAIN SELECT * FROM addresses

나 에게이 결과를 제공합니다 :

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

가상 박스, 젠 또는 다른 것? 호스트 디스크는 어떻게 설정됩니까? 같은 상자에 다른 VM도 느리게 실행됩니까? 그 질문에 대답하면 대답이 밝혀 질 수 있습니다.
Matt

저는 하이퍼 바이저의 소유자가 아니므로 실제로 대답 할 수 없습니다. 이미 하이퍼 바이저 관리자에게 최근 변경 사항을 알고 있는지 문의했지만 거절했습니다.
tabb

가능하면 mysql을 종료하고 디스크 및 메모리 벤치 마크를 실행하십시오. 복잡 할 필요는 없습니다. 아이디어는 mysql에 문제가 있거나, 아래 답변에 표시된 색인 문제이거나 더 널리 퍼져있는 경우 분리하는 것입니다.
Matt

좋은 지적은 아마 mysql 문제가 아니라는 것입니다. 실행 mysql -u username -ppassword mydb -e 'SELECT * FROM addresses은 느리게 출력되지만`> test.txt`를 추가하면 매우 빠르게 실행됩니다. 이제 이것은 아마도 다른 질문 일 것입니다!? 이것에 대해 어떻게 조사 할 수 있습니까?
tabb

하이퍼 바이저 소유자에게 연락하여 로그에 오류가 있는지 확인하도록 요청하십시오. 특히 디스크 오류. 그에게 증상을 말하십시오. 백업 지금.
Matt

답변:


13

CPU로드가 낮 으면 인덱스 누락에 문제가 없음을 나타내며,이 경우 쿼리에 CPU 및 디스크 액세스가 더 필요합니다. 또한 3 년 동안 잘 작동한다고 말했습니다.

일반적인 디스크 액세스 속도 (특히 데이터베이스가있는 파티션에서)를 확인 했습니까? 예를 dd 들어 here과 같이 사용 하십시오 . 당신이 묘사하는 것은 죽은 디스크 또는 반 데드 레이드처럼 들립니다. 내가 원하는 백업이 있습니까?


그건 좋은 지적이야. 호스트의 디스크 오류처럼 간단 할 수 있습니다.
Matt

9

몇 가지를 시도해 볼 수 있습니다.

  1. 색인 설정이 있습니까?

인덱싱을 통해 전체 테이블 스캔을 먼저 수행하지 않고도 레코드를 빠르게 찾을 수 있으므로 실행 시간이 크게 줄어 듭니다.

CREATE INDEX idx_name ON addresses(name);
  1. 쿼리를 실행하기 전에 먼저 EXPLAIN 키워드를 사용하십시오.

SELECT 쿼리 앞에서 사용될 때, MySQL이 쿼리를 실행하려는 방법과 완료하기 전에 처리해야하는 행 수를 설명합니다.

  1. VM이 RAM을 늘리면 mysql.ini를 약간 변경하고 성능이 향상되는지 확인하려면 mysql.ini를 구성하십시오.

당신을 안내 할 수있는 많은 MySQL 최적화 프로그램이 있습니다.

도움이됩니다


좋아,하지만 아주 작은 테이블 (<800 행)에 인덱스를 만드는 것이 필요한만큼 도움이되지 않는 것 같습니다. 위에서 인용 한 쿼리를 완료하는 데 1 분 이상 걸립니다. 이러한 작은 테이블의 전체 테이블 스캔에는 시간이 오래 걸리지 않습니다.
tabb

그래서 ... 색인을 추가 했습니까? 문제가 무엇인지 확실하지 않은 경우 기본을 시작하고 아래로 내려갑니다. 인덱스를 추가하면 올바르게 수행 된 경우에만 성능이 향상됩니다.
Anthony Fornito

예, 이름 열에 색인을 추가했습니다. 그러나 위의 쿼리에는 WHERE 절을 제한하지 않으므로 전체 테이블을 읽고 인쇄해야합니다. 색인이 도움이되지 않는다고 추가했습니다.
tabb

위의 EXPLAIN 쿼리 결과를 추가했습니다. 이것은 나에게는 잘 보이지만 성능은 여전히 ​​낮습니다. 가상화 관리자의 관리자가 아니므로 RAM을 늘릴 수 없습니다. 그러나 htop2050MB RAM 중 307MB 만 사용됨을 보여줍니다.
tabb

인덱스에 대해 실제로 인덱스 할 열에 대해 생각할 필요가 있습니다. 모든 것을 인덱싱하고 가장 많은 양을 가진 인덱스를 인덱싱하고 싶지는 않습니다. 나는 이것에 대해 약간의 가정을하고 있지만 name'firstname'으로 시작 합니다. 둘째, 색인을 올바르게 작성 했습니까? possible_keys : 열이 NULL 인 경우 NULL은 관련 인덱스를 찾을 수 없음을 나타냅니다.
Anthony Fornito
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.