500000+ 개의 행을 가진 메인 테이블을 가지고 있습니다.MySQL은 JOIN 쿼리에서 인덱스를 사용하지 않습니다.
CREATE TABLE `esc_questions`(
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`esc_id` INT(11) NOT NULL,
`question_text` LONGTEXT COLLATE utf8_unicode_ci NOT NULL,
`answer_1` TEXT COLLATE utf8_unicode_ci NOT NULL,
`answer_2` TEXT COLLATE utf8_unicode_ci NOT NULL,
`answer_3` TEXT COLLATE utf8_unicode_ci NOT NULL,
`answer_4` TEXT COLLATE utf8_unicode_ci NOT NULL,
`answer_5` TEXT COLLATE utf8_unicode_ci NOT NULL,
`right_answer` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL,
`disciplinas_id` INT(11) UNSIGNED NOT NULL,
`assunto_id` INT(11) UNSIGNED NOT NULL,
`orgao_id` INT(11) UNSIGNED NOT NULL,
`cargo_id` INT(11) UNSIGNED NOT NULL,
`ano` INT(11) NOT NULL,
`banca_id` INT(11) UNSIGNED NOT NULL,
`question_type` TINYINT(4) NOT NULL,
`url` TEXT COLLATE utf8_unicode_ci NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `idx_ano`(`ano`) USING BTREE,
KEY `idx_question_type`(`question_type`) USING BTREE,
KEY `idx_cargo_id`(`cargo_id`) USING BTREE,
KEY `idx_orgao_id`(`orgao_id`) USING BTREE,
KEY `idx_banca_id`(`banca_id`) USING BTREE,
KEY `idx_question_id`(`id`) USING BTREE,
KEY `idx_assunto_id`(`assunto_id`) USING BTREE,
KEY `idx_disciplinas_id`(`disciplinas_id`) USING BTREE,
CONSTRAINT `fk_assunto_id` FOREIGN KEY(`assunto_id`) REFERENCES `esc_assunto`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_banca_id` FOREIGN KEY(`banca_id`) REFERENCES `esc_bancas`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_cargo_id` FOREIGN KEY(`cargo_id`) REFERENCES `esc_cargo`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_disciplinas_id` FOREIGN KEY(`disciplinas_id`) REFERENCES `esc_disciplinas`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_orgao_id` FOREIGN KEY(`orgao_id`) REFERENCES `esc_orgao`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB AUTO_INCREMENT = 516157 DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci
관련 데이터는이 매우 유사 5 개 개의 추가 테이블에 저장됩니다
CREATE TABLE `esc_assunto`(
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `idx_assunto_id`(`id`) USING BTREE,
KEY `idx_assunto_name`(`name`(30)),
CONSTRAINT `fk_assunto` FOREIGN KEY(`id`) REFERENCES `esc_questions`(`assunto_id`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = INNODB AUTO_INCREMENT = 3618 DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci
내 웹 사이트에 페이지 매김이있다. 최신 페이지를 얻으려고 할 때 데이터 요청에 걸리는 시간이 증가하고 있습니다. 다음은이 작업을위한 나의 선택이다 :
SELECT
f.*,
d.name disciplinas,
o.name orgao,
c.name cargo,
b.name banca,
a.name assunto
FROM
`esc_questions` f
INNER JOIN
`esc_bancas` b
ON
f.banca_id = b.id
INNER JOIN
`esc_disciplinas` d
ON
f.disciplinas_id = d.id
INNER JOIN
`esc_assunto` a
ON
f.assunto_id = a.id
INNER JOIN
`esc_orgao` o
ON
f.orgao_id = o.id
INNER JOIN
`esc_cargo` c
ON
f.cargo_id = c.id
LIMIT 400020, 20
이 쿼리는 Sending Data
단계는 쿼리 프로파일에 나타났다에 시간이 오래 걸립니다.
Sending Data 17.6 s 99.99% 1 17.6 s
는 EXPLAIN
다음 보여준다
1 SIMPLE D ALL PRIMARY을 247
1 SIMPLE F REF idx_cargo_id, idx_orgao_id, idx_banca_id, idx_assunto_id, idx_disciplinas_id idx_disciplinas_id 4 concursos.d.id 1,116
을 idx_disciplinas_id eq_ref PRIMARY O 1 SIMPLE, idx_orgao_id PRIMARY 4 concursos.f.orgao_id 1
1 간단한 C eq_ref 차, 4 idx_cargo_id PRIMARY concursos.f.cargo_id 1
간단 eq_ref의 PRIMARY, idx_assunto_id PRIMARY 4 concursos.f.assunto_id 1
1 SIMPLE B의 eq_ref의 PRIMARY, idx_bancas_id PRIMARY 4 concursos.f.banca_id 1
나는이 작업을 빠르게하기 위해 하루 종일 보냈지 만 성공하지 못했습니다.
누가 내 선택 쿼리가 잘못되었거나 MySQL이 인덱스를 사용하지 않는 이유를 말해 줄 수 있습니까?
도움을 주시면 감사하겠습니다.
1. PRIMARY 키에도 ORDER BY를 사용하면 Extra가 추가됩니다. EXPLAIN에서 filesort를 사용하고 있으며이 쿼리의 속도가 향상되지 않습니다. 첫째로 ORDER BY와 함께했습니다. 2. ID가 순차적이지 않으므로 % 이상의 WHERE id를 사용할 수 없습니다. 그러나 나는로드 타임을 테스트하고 정말로 빨라졌습니다. – ganchclub