Здравствуйте, снова хорошие люди Stackoverflow. Основываясь на нескольких ответах на подобные вопросы, я полагаю, что добавление индексов в мои таблицы поможет выполнить запрос ниже. Задача состоит в том, что я не слишком хорошо знаком или удобен с использованием индексов, поскольку, по-видимому, существует потенциал замедления других запросов при использовании слишком большого количества индексов. Просто найдите кого-то, кто поможет мне в правильном направлении. Заранее благодарю за помощь.MySql, индексирование и ускорение запроса
Запрос:
SELECT
territories.territoryID,
territories.territory_name,
territories_meta.tm_color,
territories.territory_description,
territories.territory_state,
GROUP_CONCAT(distinct(territories_zips.tz_zip)SEPARATOR ', ') AS ZipCodes,
count(distinct(users.userID)) as AgentsAssigned,
GROUP_CONCAT(distinct(concat(users.user_Fname,' ',users.user_Lname))SEPARATOR ', ')
AS AgentName,
a.sumTerr as TotalOpp
from(
SELECT
territories_zips.tz_terrID as terrID,
sum(boundaries_meta.bm_opportunity) as sumTerr
FROM territories_zips
INNER JOIN boundaries ON boundaries.boundary_name = territories_zips.tz_zip
INNER JOIN boundaries_meta ON boundaries.boundary_id = boundaries_meta.bm_boundariesID
where tz_status = 1
group by tz_terrID
)as a
inner join territories on territories.territoryID = a.terrId
INNER JOIN territories_zips ON territories.territoryID = territories_zips.tz_terrID
INNER JOIN territories_assign ON territories.territoryID = territories_assign.ta_territoryID
INNER JOIN users ON users.userID = territories_assign.ta_repID
INNER JOIN territories_meta ON territories_meta.tm_territoryID = territories.territoryID
WHERE
territories_zips.tz_status = 1 AND
territories_assign.ta_repStatus = 1 AND
users.user_status = 1
GROUP BY territoryID
Объясните:
id select_type table typw possible_keys key key_len ref rows extra
1 PRIMARY <derived2> ALL 97 Using temporary; Using filesort
1 PRIMARY territories_meta ALL 121 Using where; Using join buffer
1 PRIMARY territories_zips ALL 1739 Using where; Using join buffer
1 PRIMARY territories_assign ALL 138 Using where; Using join buffer
1 PRIMARY users eq_ref PRIMARY PRIMARY 8 msb_db.territories_assign.ta_repID 1 Using where
1 PRIMARY territories eq_ref PRIMARY PRIMARY 8 msb_db.territories_meta.tm_territoryID 1 Using where
2 DERIVED territories_zips ALL 1739 Using where; Using temporary; Using filesort
2 DERIVED boundaries_meta ALL 42995 Using join buffer
2 DERIVED boundaries eq_ref PRIMARY PRIMARY 4 msb_db.boundaries_meta.bm_boundariesID 1 Using where
Я думаю, что виновник является этой частью подзапроса как он занимает всего 2 секунды меньше, чтобы запустить эту часть по сравнению с всем запросом выше ,
SELECT
territories_zips.tz_terrID as terrID,
sum(boundaries_meta.bm_opportunity) as sumTerr
FROM territories_zips
INNER JOIN boundaries ON boundaries.boundary_name = territories_zips.tz_zip
INNER JOIN boundaries_meta ON boundaries.boundary_id = boundaries_meta.bm_boundariesID
where tz_status = 1
group by tz_terrID
и это объясняет:
id select_type table typw possible_keys key key_len ref rows extra
1 SIMPLE territories_zips ALL 1739 Using where; Using temporary; Using filesort
1 SIMPLE boundaries_meta ALL 42995 Using join buffer
1 SIMPLE boundaries eq_ref PRIMARY PRIMARY 4 mb_db.boundaries_meta.bm_boundariesID 1 Using where
Я включил таблицы ниже для этого подвида запроса, пожалуйста, дайте мне знать, если мне нужно перепечатывать другие структуры таблиц
Таблицы:
CREATE TABLE `boundaries` (
`boundary_id` int(11) NOT NULL AUTO_INCREMENT,
`boundary_name` varchar(20) DEFAULT NULL,
`geometry_type` varchar(12) DEFAULT NULL,
`boundary_geometry` mediumtext,
`boundary_type` varchar(5) DEFAULT NULL,
`boundary_state` varchar(4) DEFAULT NULL,
PRIMARY KEY (`boundary_id`)
) ENGINE=MyISAM AUTO_INCREMENT=64504 DEFAULT CHARSET=utf8;
CREATE TABLE `boundaries_meta` (
`boundaries_metaID` bigint(20) NOT NULL AUTO_INCREMENT,
`bm_boundariesID` bigint(20) NOT NULL,
`bm_opportunity` int(5) NOT NULL,
PRIMARY KEY (`boundaries_metaID`)
) ENGINE=MyISAM AUTO_INCREMENT=51201 DEFAULT CHARSET=utf8;
CREATE TABLE `territories_zips` (
`terr_zipsID` bigint(10) NOT NULL AUTO_INCREMENT,
`tz_terrID` bigint(10) NOT NULL,
`tz_zip` varchar(5) CHARACTER SET latin1 NOT NULL,
`tz_status` smallint(1) NOT NULL,
PRIMARY KEY (`terr_zipsID`)
) ENGINE=MyISAM AUTO_INCREMENT=2576 DEFAULT CHARSET=utf8;
Еще раз благодарю вас за помощь.
EDIT: Я обновил некоторые таблицы с индексами и получил невероятное улучшение (еще раз спасибо королю Исааку). Я включаю новое объяснение в подзапрос, поскольку мне все еще не нравится, как и почему это помогло, или если я действительно создал индексы в правильных частях. Дайте человеку рыбу, он съедает за день, научи его ловить рыбу, и ....
id select_type table type possible keys key key_len ref rows extra
1 SIMPLE territories_zips ALL 1739 Using where; Using temporary; Using filesort
1 SIMPLE boundaries ref PRIMARY,bndIDindex,bndNameindex bndNameindex 63 func 1 Using where
1 SIMPLE boundaries_meta eq_ref bmBndIDindex bmBndIDindex 8 mb_db.boundaries.boundary_id 1 Using where
Спасибо, королю Исааку. Очень тщательный обзор, я с нетерпением жду, чтобы копаться в ваших очках и скоро вернусь с некоторыми ответами и, вероятно, с большим количеством вопросов. – alex
В отношении первого вопроса: tz_zip и имя_границы не уникальны. Я не совсем уверен, что такое стандартный индекс или как я могу применить его в этом случае к любому из двух. Теперь я рассмотрю суб-запрос. Еще раз спасибо – alex
Конечно, вам стоит поставить уникальный индекс, где вы можете. Под «стандартным индексом» я имел в виду тот, который можно просто добавить через «ALTER TABLE ADD INDEX». http://dev.mysql.com/doc/refman/5.1/en/alter-table.html –