MySQL은 데이터를 전송하는 데 너무 오래 걸린다


9

수백만 개의 레코드 (14,000,000)가있는 간단한 테이블이 있고 간단한 쿼리의 경우 "데이터 전송"에 너무 많은 시간을 소비하고 있습니다.

탁자

CREATE TABLE IF NOT EXISTS details (
  id int(11) NOT NULL,
  date date NOT NULL,
  time int(2) NOT NULL,
  minutes_online decimal(5,0) NOT NULL,
  minutes_playing decimal(5,0) NOT NULL,
  minutes_chatting decimal(5,0) NOT NULL,
  minutes_away decimal(5,0) NOT NULL
  PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

간단한 쿼리

mysql> SELECT * FROM details WHERE id = 3014595;

설명

mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table     | type | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | details   | ref  | PRIMARY       | PRIMARY | 4       | const | 1482 |       |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+

쿼리 프로필

mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions           | 0.000014 |
| Opening tables                 | 0.000126 |
| System lock                    | 0.000011 |
| Table lock                     | 0.000030 |
| init                           | 0.000027 |
| optimizing                     | 0.000117 |
| statistics                     | 0.040077 |
| preparing                      | 0.000029 |
| executing                      | 0.000006 |
| Sending data                   | 7.536960 |
| end                            | 0.000013 |
| query end                      | 0.000004 |
| freeing items                  | 0.000037 |
| storing result in query cache  | 0.000006 |
| logging slow query             | 0.000003 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

보다시피, SELECT명령문은 인덱스를 사용하고 1482 행만 읽습니다. 그러나 쿼리는 데이터를 보내는 데 7.536960 초가 걸렸습니다. 쿼리가 필요한 행을 훨씬 더 많이 읽는 것과 같습니다.

7 개의 필드 (행 평균 59 바이트)와 간단한 기능이없는 간단한 쿼리입니다. 이 문제를 일으킬 수있는 아이디어가 있습니까?

참고 : id는 사용자 ID입니다. 각 사용자는 매일 1 시간마다 하나 이상의 항목을 가질 수 있습니다. 따라서 id는 고유하지 않습니다.

편집 : 동일한 구조와 훨씬 더 많은 행 (34 백만)을 가진 다른 테이블이 있습니다. 이 큰 테이블에서 동일한 쿼리를 실행하면 결과가 1 초 미만으로 반환됩니다.

유일한 차이점은 큰 테이블은 작은 테이블만큼 많은 쿼리를 얻지 못한다는 것입니다.

  • 쿼리 수가 프로세스 속도를 늦출 수 있습니까? MySQL 캐시가 켜져 있습니다. 또한 CakePHP는 쿼리 수를 줄이기 위해 쿼리를 캐싱했습니다.
  • 테이블이 저장된 파일이 손상되었거나 무엇입니까?

업데이트이 문제는 웹 계층에서 데이터 계층을 분리하여 해결되었습니다. 데이터 계층도 RAM에서 업그레이드되었으며 raid10에서 실행 중입니다.


SELECT반환되는 행 수는 몇 개 입니까?
hjpotter92

1591 rows in set (16.48 sec)쿼리를 다시 실행했는데 지속 시간이 다른 이유입니다. 이제 16 초가 걸렸습니다 (!!)
rlcabral

* 대신 열을 사용하고 그 차이를 확인하십시오.
Muhammad Raheel

아니. 같은 결과입니다.
rlcabral

ID 열을 간단한 기본 색인으로 만드십시오. ID는 고유 한 필드이므로 복잡한 색인을 만들 필요가 없습니다. 기본 속도로 빠른 속도로 검색 할 수 있습니다.
Alexander Pravdin

답변:


1

RAM을 업그레이드하지 않아도이 질문에 걸려 넘어져서 궁금해하는 사람은 왜 데이터를 보내는 데 시간이 오래 걸립니까? 전송 데이터에는 실제로 전송 될 데이터를 검색하는 시간이 포함되기 때문입니다.

https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html

스레드가 SELECT 문의 행을 읽고 처리하고 클라이언트에 데이터를 전송 중입니다. 이 상태에서 발생하는 작업은 많은 양의 디스크 액세스 (읽기)를 수행하는 경향이 있기 때문에 주어진 쿼리 수명 동안 가장 오래 실행되는 상태입니다.


-2

Optimize table tablename을 사용하여 테이블을 최적화하고 상태를 확인하십시오.

큰 변화가 필요합니다 :

Alter table tablename engine = 'INNODB'

이렇게하면 많은 도움이되고 테이블에 하나의 기본 키가 있어야하지만 세 개의 열을 기본 키로 추가했습니다.


-3

id에 대한 별도의 색인을 만듭니다.

테이블 세부 사항 변경 키 추가 d1 (id);

이 인덱스를 적용하려면 MySQL을 다시 시작하거나

테이블 세부 사항 분석;

가능하면 트랜잭션 지원 및 기타 이점을 위해 데이터베이스를 InnoDB로 변경할 수도 있습니다.


이것이 어떻게 도움이 되나요?
Colin 't Hart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.