как оптимизировать запрос mysql: подсчет категории и подкатегории с помощью одного запроса из двух таблиц
мне нужна помощь для оптимизации этого запроса MySQL для лучшей и быстрой производительности.
здесь SQL FIDDLE
с запросом и структурой таблицы.
в принципе у меня есть две таблицы
tbl_category
CREATE TABLE IF NOT EXISTS `tbl_category` (
`category_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_name` varchar(20) NOT NULL,
`parent_category_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`category_id`),
UNIQUE KEY `category_name` (`category_name`,`parent_category_id`),
KEY `category_parent_id` (`parent_category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- data for table `tbl_auction`
--
+-------------+---------------+--------------------+-----------------+
| category_id | category_name | parent_category_id | category_status |
+-------------+---------------+--------------------+-----------------+
| 1 | Boats | NULL | a |
| 2 | Books | NULL | a |
| 3 | Building | NULL | a |
| 4 | Cars | NULL | a |
| 5 | Electrical | 3 | a |
| 6 | Hardware | 3 | a |
| 7 | Heating | 3 | a |
| 8 | Miscellaneous | 3 | a |
| 9 | Plumbing | 3 | a |
| 10 | Tools | 4 | a |
| 11 | Lights | 4 | a |
| 12 | Miscellaneous | 4 | a |
+-------------+---------------+--------------------+-----------------+
tbl_auction
CREATE TABLE IF NOT EXISTS `tbl_auction` (
`auction_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`auction_category` int(10) unsigned NOT NULL
COMMENT 'either store subcategory OR main category if no subcategory',
`auction_title` varchar(100) NOT NULL,
PRIMARY KEY (`auction_id`),
KEY `auction_category` (`auction_category`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- data for table `tbl_auction`
--
+------------+------------------+---------------+
| auction_id | auction_category | auction_title |
+------------+------------------+---------------+-
| 1 | 1 | one |
| 2 | 2 | two |
| 3 | 5 | five |
| 4 | 6 | six |
| 5 | 5 | five2 |
| 6 | 8 | eight |
| 7 | 11 | eleven |
| 8 | 11 | eleven2 |
| 9 | 10 | ten |
| 10 | 2 | two2 |
| 11 | 12 | twelve |
+------------+------------------+---------------+
теперь я хочу подсчитать все категории аукционов мудрым, а также если какая-то категория имеет подкатегорию, то суммировать этот аукцион в основную категорию
Я сделал ниже запрос
SELECT auction_category AS categoryID, COUNT(*) AS total
FROM `tbl_auction`
GROUP BY auction_category
UNION ALL
SELECT parent_category_id AS categoryID, COUNT( * ) AS total
FROM `tbl_auction` ta
INNER JOIN tbl_category tc ON tc.category_id = ta.auction_category
WHERE parent_category_id IS NOT NULL
GROUP BY parent_category_id
хотя выше запрос возвращает ожидаемые результаты но я думаю, что может быть какой-то оптимизированный способ решить эту проблему. пожалуйста, направьте меня и предложите мне оптимизированный запрос.
спасибо
1 ответов
что такое производительность убийства-это filesort, вызванный одним из GROUP BY
и/или UNION
. Вы можете переписать запрос без UNION
as:
SELECT pcat.category_id, COUNT(*)
FROM tbl_category pcat
LEFT JOIN tbl_category subcat
ON subcat.parent_category_id = pcat.category_id
INNER JOIN tbl_auction a
ON a.auction_category = IFNULL(subcat.category_id,pcat.category_id)
GROUP BY pcat.category_id;
это имеет тот же эффект (двойной подсчет каждого аукциона, один раз под его подкатом, один раз под родительской кошкой), и EXPLAIN
показывает никаких filesort работа. Если это происходит, когда данные становятся больше, вы можете попробовать добавить ORDER BY NULL
трюк.
также, если точность в реальном времени не очень важна, но запрос выполняется часто закешировать результат.