죄송합니다. 제목에 대해 더 구체적으로 설명 드릴 수 없습니다. 긴 MySql 쿼리에서 인덱스 최적화
그래서 나는이 쿼리 가지고 :CREATE TABLE RecordPoints AS (
SELECT competitionId, personId, personCountryId, eventId, year, date,
if(regionalAverageRecord = 'WR',
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date AND rd.average > 0), 0) wrAveragePoints,
if(regionalSingleRecord = 'WR',
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date), 0) wrSinglePoints,
if(NOT regionalAverageRecord in('WR', 'NR'),
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date AND average > 0 AND rd.personCountryId in
(SELECT Countries.id FROM Countries JOIN Continents on Countries.continentId=Continents.id where recordName = rd2.regionalAverageRecord)), 0) crAveragePoints,
if(NOT regionalAverageRecord in('WR', 'NR'),
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date AND rd.personCountryId in
(SELECT Countries.id FROM Countries JOIN Continents on Countries.continentId=Continents.id where recordName = rd2.regionalSingleRecord)), 0) crSinglePoints,
if(regionalAverageRecord = 'NR',
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date AND rd.personCountryId=rd2.personCountryId AND rd.average > 0), 0) nrAveragePoints,
if(regionalSingleRecord = 'NR',
(SELECT COUNT(DISTINCT personId) FROM ResultDates rd
WHERE rd.eventId=rd2.eventId AND rd.date <= rd2.date AND rd.personCountryId=rd2.personCountryId), 0) nrSinglePoints
FROM ResultDates rd2 WHERE (NOT regionalAverageRecord='' OR NOT regionalSingleRecord = ''));
을 그리고 그것은 완료 9시간했다. 그것을 분해하기 위해, 필자는 열 6 개가 전체 하위 쿼리인데, 여기에서 date와 몇 가지를 기준으로 한 일이 발생하기 전에 동일한 테이블에 personId가 몇 번 나타나는지 계산합니다. 다른 열. CREATE INDEX date ON ResultDates (date)
을 사용하여 날짜에 색인을 생성하는 것은 생각보다 조금 빨라졌지만 여전히 괴로운 시간이 걸립니다.
+------------+-----------------+---------------+---------+---------+-----+---------+----------------------+-----------------------+-------+-----+------+------------+
| personId | personCountryId | competitionId | eventId | roundId | pos | average | regionalSingleRecord | regionalAverageRecord | month | day | year | date |
+------------+-----------------+---------------+---------+---------+-----+---------+----------------------+-----------------------+-------+-----+------+------------+
| 1982THAI01 | USA | WC1982 | 333 | f | 1 | 0 | WR | | 6 | 5 | 1982 | 1982-06-05 |
+------------+-----------------+---------------+---------+---------+-----+---------+----------------------+-----------------------+-------+-----+------+------------+
같은 ResultDates
찾는
행 regionalSingleRecord 및 regionalAverageRecord이 "RecordNames"의가 될 수 있습니다 : WR를, NR, 아무것도 대부분의 시간, 또는 AFR, ASR, ER, NAR, OCR , SAR을 사용하여 그 recordNames가 연결되어있는 대륙을 기반으로 한 국가를 찾습니다.
이 레코드 이름을 대륙에 연결하고 대륙 id를 countryIds에 연결하는 색인을 만들었지 만 속도가 어느 정도 향상되었는지는 알 수 없습니다.
그것을 EXPLAIN 실행하면이 나에게 반환
+----+--------------------+------------+------------+------+-------------------+--------------+---------+----------------------------------+--------+----------+---------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+------------+------------+------+-------------------+--------------+---------+----------------------------------+--------+----------+---------------------------------------------------------------+
| 1 | PRIMARY | rd2 | NULL | ref | idx_personId | idx_personId | 32 | const | 567 | 99.00 | Using where |
| 9 | DEPENDENT SUBQUERY | rd | NULL | ALL | date,idx_personId | NULL | NULL | NULL | 992294 | 0.33 | Range checked for each record (index map: 0x3) |
| 8 | DEPENDENT SUBQUERY | rd | NULL | ALL | date,idx_personId | NULL | NULL | NULL | 992294 | 0.11 | Range checked for each record (index map: 0x3) |
| 6 | DEPENDENT SUBQUERY | Continents | NULL | ref | P_id,recordIndex | recordIndex | 9 | cubing.rd2.regionalSingleRecord | 1 | 100.00 | Using index; Start temporary |
| 6 | DEPENDENT SUBQUERY | Countries | NULL | ALL | NULL | NULL | NULL | NULL | 203 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
| 6 | DEPENDENT SUBQUERY | rd | NULL | ALL | date | NULL | NULL | NULL | 992294 | 0.33 | Range checked for each record (index map: 0x1); End temporary |
| 4 | DEPENDENT SUBQUERY | Continents | NULL | ref | P_id,recordIndex | recordIndex | 9 | cubing.rd2.regionalAverageRecord | 1 | 100.00 | Using index; Start temporary |
| 4 | DEPENDENT SUBQUERY | Countries | NULL | ALL | NULL | NULL | NULL | NULL | 203 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
| 4 | DEPENDENT SUBQUERY | rd | NULL | ALL | date | NULL | NULL | NULL | 992294 | 0.11 | Range checked for each record (index map: 0x1); End temporary |
| 3 | DEPENDENT SUBQUERY | rd | NULL | ALL | date,idx_personId | NULL | NULL | NULL | 992294 | 3.33 | Range checked for each record (index map: 0x3) |
| 2 | DEPENDENT SUBQUERY | rd | NULL | ALL | date,idx_personId | NULL | NULL | NULL | 992294 | 1.11 | Range checked for each record (index map: 0x3) |
+----+--------------------+------------+------------+------+-------------------+--------------+---------+----------------------------------+--------+----------+---------------------------------------------------------------+
나는 그것의 속도를 개선하는 방법에 대한 몇 가지 인터넷 검색을 해왔습니다. 내 인터넷 검색을 기반으로, 나는 그것이 좋지 않다는 것을 안다. 특히 초기 테이블에있는 992294 행을보고 있습니다.
내 문제는이 모든 것을 더 빠르게 최적화하는 방법을 모르겠다는 것입니다. 신중하게 만들어진 인덱스는 속도를 향상시킬 수 있으므로 어떤 인덱스를 사용할 수 있는지 궁금합니다.