Mysql - Using temporary. Mysql создает временную таблицу при условии where
В базе данных есть таблица районов, новостей и связующая новости с районами, так как одна новость может отображаться на нескольких районах.
Есть скрипт
select news.id
from `news`
inner join `news_rayon` on `news_rayon`.`news_id` = `news`.`id`
where `news`.`type` = 'news'
and `news_rayon`.`rayon_id` = 20
order by `public_date` desc
limit 25 offset 0
EXPLAIN показывает что для таблицы news_rayon использується 189320 rows и Using index condition; Using temporary; Using filesort.
Таблица новостей имеет больше милиона записей и соответственно news_rayon еще больше.Также таблица новостей имеет поле type которое делит их на типы news, topics, bogs.
Запрос который в примере, выполняеться 14 секунд. Если убрать условие news_rayon`.`rayon_id` = 20 тогда мгновенно. Либо когда я указываю USE INDEX (news_public_date_index), также мгновенно.
Созданы связи и проставлены индексы для столбцов.
Игрался с изменениями параметров памяти для сортировки и других настроек. Не работает. Уже незнаю куда копать
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `news` (
`id` int(10) unsigned NOT NULL,
`type` varchar(10) NOT NULL,
`rayon_id` int(11) unsigned NOT NULL,
`status` tinyint(4) NOT NULL DEFAULT 2,
`public_date` datetime DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`description` varchar(500) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `news_rayon` (
`id` int(10) unsigned NOT NULL,
`rayon_id` int(10) unsigned NOT NULL,
`news_id` int(10) unsigned NOT NULL,
`is_moder` tinyint(1) DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `rayons` (
`id` int(10) unsigned NOT NULL,
`sub_domain` varchar(255) NOT NULL,
`region_id` int(10) unsigned DEFAULT NULL ,
`status` smallint(6) NOT NULL DEFAULT 0,
`published` smallint(6) NOT NULL DEFAULT 0,
`name` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `news`
ADD PRIMARY KEY (`id`),
ADD KEY `news_public_date_index` (`public_date`),
ADD KEY `type` (`type`);
ALTER TABLE `news_rayon`
ADD PRIMARY KEY (`id`),
ADD KEY `news_rayon_news_id_foreign` (`news_id`),
ADD KEY `news_rayon_rayon_id_foreign` (`rayon_id`);
ALTER TABLE `rayons`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `rayons_sub_domain_unique` (`sub_domain`),
ADD KEY `name` (`name`);
ALTER TABLE `news`
MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;
ALTER TABLE `news_rayon`
MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;
ALTER TABLE `rayons`
MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;
ALTER TABLE `news_rayon`
ADD CONSTRAINT `news_rayon_ibfk_1` FOREIGN KEY (`rayon_id`) REFERENCES `rayons` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `news_rayon_ibfk_2` FOREIGN KEY (`news_id`) REFERENCES `news` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
