수백만 개의 레코드 (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로 변경할 수도 있습니다.