MySQL은 데이터를 전송하는 데 너무 오래 걸린다 간단한 테이블이

수백만 개의 레코드 (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에서 실행 중입니다.



답변

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

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

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


답변

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

큰 변화가 필요합니다 :

Alter table tablename engine = 'INNODB'

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


답변

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

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

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

테이블 세부 사항 분석;

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