|
|
|
| Здравствуйте, уважаемые пользователи форума Softtime.ru. Всегда интересовал меня вопрос, как можно спросить (оптимизировать) следующий MYSQL запрос:
SELECT (SELECT COUNT(*) FROM `XeronUsers` WHERE `status` = 'ACTIVE') as active, (SELECT COUNT(*) FROM `XeronUsers` WHERE `status` = 'BLOCKED') as blocked, (SELECT COUNT(*) FROM `XeronUsers` WHERE `status` != 'ACTIVE' AND `status` != 'BLOCKED') as others
|
Заранее спасибо, буду очень благодарен. | |
|
|
|
|
|
|
|
для: pavluxa09
(19.05.2012 в 14:25)
| | А под "спросить (оптимизировать)" что имеется в виду, запрос выполняется слишком медленно? | |
|
|
|
|
|
|
|
для: cheops
(19.05.2012 в 14:54)
| | Нет, но наверняка вложенность запросов забирает много лишних ресурсов | |
|
|
|
|
|
|
|
для: pavluxa09
(19.05.2012 в 14:25)
| | Без вложенных запросов не получится, но можно сделать не с 3мя подзапросами, а с одним:
SELECT stat,count(*) AS co FROM
(SELECT CASE WHEN status='ACTIVE' THEN 'active'
WHEN status='BLOCKED' THEN 'blocked'
ELSE 'others' END AS stat
FROM XeronUsers)t
GROUP BY stat
| правда данные будут не в столбцах, а в строках. Примерно так
+---------+----+
| stat | co |
+---------+----+
| active | 25 |
| blocked | 34 |
| others | 56 |
+---------+----+
|
| |
|
|
|
|
|
|
|
для: Sfinks
(19.05.2012 в 15:33)
| | А это будет меньше ресурсов кушать? | |
|
|
|
|
|
|
|
для: pavluxa09
(19.05.2012 в 21:16)
| | Прогоните оба запроса через EXPLAIN и выложите результаты (очень сильно все зависит от объема таблиц и ключей). | |
|
|
|
|
|
|
|
для: cheops
(19.05.2012 в 21:23)
| | ПРедложенный Вами запрос возвращает:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
2 DERIVED XeronUsers ALL NULL NULL NULL NULL 3
А мой запрос :
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
4 SUBQUERY XeronUsers ALL NULL NULL NULL NULL 3 Using where
3 SUBQUERY XeronUsers ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY XeronUsers ALL NULL NULL NULL NULL 3 Using where | |
|
|
|
|
|
|
|
для: pavluxa09
(20.05.2012 в 11:23)
| | Первый запрос использует временную таблицу на жестком диске, второй её вроде как не использует, но зато перебирает больше столбцов, вообще бы индексы нужно вводить. Однако, если у вас будет 3 записи - все-равно какой запрос, все будет быстро работать. | |
|
|
|
|
|
|
|
для: cheops
(20.05.2012 в 21:51)
| | а если будет около милиона? | |
|
|
|
|
|
|
|
для: pavluxa09
(21.05.2012 в 14:53)
| | Будет плохо, впрочем, если у вас будут такие объемы, я бы порекомендовал бы вам время от времени осуществлять подсчет количеств по cron-заданию (внешнему или MySQL) и складировать их в отдельную таблицу, откуда данные и извлекать по мере надобности (особенно, если этот запрос будет выполняться довольно часто). | |
|
|
|
|
|
|
|
для: cheops
(21.05.2012 в 16:45)
| | Понял. Спасибо. | |
|
|
|
|
|
|
|
для: pavluxa09
(21.05.2012 в 19:09)
| | Попробуйте еще такой запрос:
SELECT st, sum(co) co
FROM( SELECT co, IF( st!='active' AND st!='blocked', 'others', st ) st
FROM( SELECT count(*) co, status st FROM XeronUsers GROUP BY st )t )t
GROUP BY st
|
Хотя выглядит страшнее, но работает быстрее.
Только вы сделайте в таблице хотя б 100 записей, чтоб было заметно откуда ноги растут..... А то 3 записи, 3 запроса - не показательно! И прогоните с 100 записями все 3 запроса через EXPLAIN | |
|
|
|
|
|
|
|
для: Sfinks
(25.05.2012 в 01:55)
| | Спасибо, сейчас сделаем! | |
|
|
|