У меня следующий запрос
SELECT SUBSTRING(a0_.created_date FROM 1 FOR 10) AS sclr_0,
COUNT(1) AS sclr_1
FROM applications a0_ INNER JOIN
package_codes p1_ ON a0_.id = p1_.application_id
WHERE a0_.created_date BETWEEN '2019-01-01' AND '2020-01-01' AND
p1_.type = 'Package 1'
GROUP BY sclr_0
--- EDIT ---
Большинство из вас сосредоточено на GROUP BY и SUBSTRING, но это не является причиной проблемы.
Следующий запрос имеет одинаковое время выполнения:
SELECT COUNT(1) AS sclr_1
FROM applications a0_ INNER JOIN
package_codes p1_ ON a0_.id = p1_.application_id
WHERE a0_.created_date BETWEEN '2019-01-01' AND '2020-01-01' AND
p1_.type = 'Package 1'
--- EDIT 2 ---
После добавления индекса на application.created_date и принудительного использования запроса для указанногоИндексы @DDS предполагают, что время выполнения падает до ~ 750 мс
Текущий запрос выглядит следующим образом:
SELECT SUBSTRING(a0_.created_date FROM 1 FOR 10) AS sclr_0,
COUNT(1) AS sclr_1
FROM applications a0_ USE INDEX (applications_created_date_idx) INNER JOIN
package_codes p1_ USE INDEX (PRIMARY, UNIQ_70A9C6AA3E030ACD, package_codes_type_idx) ON a0_.id = p1_.application_id
WHERE a0_.created_date BETWEEN '2019-01-01' AND '2020-01-01' AND
p1_.type = 'Package 1'
GROUP BY sclr_0
--- EDIT 3 ---
Я нашелчто использование большого количества индексов в запросе может привести к тому, что в некоторых случаях MySQL будет использовать неоптимальные индексы, поэтому итоговый запрос должен выглядеть следующим образом:
SELECT SUBSTRING(a0_.created_date FROM 1 FOR 10) AS sclr_0,
COUNT(1) AS sclr_1
FROM applications a0_ USE INDEX (applications_created_date_idx) INNER JOIN
package_codes p1_ USE INDEX (package_codes_application_idx) ON a0_.id = p1_.application_id
WHERE a0_.created_date BETWEEN '2019-01-01' AND '2020-01-01' AND
p1_.type = 'Package 1'
GROUP BY sclr_0
--- END EDIT ---
package_codes содержит более 100 000 000 записей.
приложения содержат более 250 000 записей.
Запрос занимает 2 минуты, чтобы получить результат.Есть ли способ оптимизировать его?Я застрял на MySQL 5.5.
Таблицы:
CREATE TABLE `applications` (
`id` int(11) NOT NULL,
`created_date` datetime NOT NULL,
`name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
`surname` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `applications`
ADD PRIMARY KEY (`id`),
ADD KEY `applications_created_date_idx` (`created_date`);
ALTER TABLE `applications`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
CREATE TABLE `package_codes` (
`id` int(11) NOT NULL,
`application_id` int(11) DEFAULT NULL,
`created_date` datetime NOT NULL,
`type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`code` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`disabled` tinyint(1) NOT NULL DEFAULT '0',
`meta_data` longtext COLLATE utf8mb4_unicode_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `package_codes`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `UNIQ_70A9C6AA3E030ACD` (`application_id`),
ADD KEY `package_codes_code_idx` (`code`),
ADD KEY `package_codes_type_idx` (`type`),
ADD KEY `package_codes_application_idx` (`application_id`),
ADD KEY `package_codes_code_application_idx` (`code`,`application_id`);
ALTER TABLE `package_codes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `package_codes`
ADD CONSTRAINT `FK_70A9C6AA3E030ACD` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`);