Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как можно спросить такой запрос?
 
 автор: pavluxa09   (19.05.2012 в 14:25)   письмо автору
 
 

Здравствуйте, уважаемые пользователи форума 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


Заранее спасибо, буду очень благодарен.

  Ответить  
 
 автор: cheops   (19.05.2012 в 14:54)   письмо автору
 
   для: pavluxa09   (19.05.2012 в 14:25)
 

А под "спросить (оптимизировать)" что имеется в виду, запрос выполняется слишком медленно?

  Ответить  
 
 автор: pavluxa09   (19.05.2012 в 15:02)   письмо автору
 
   для: cheops   (19.05.2012 в 14:54)
 

Нет, но наверняка вложенность запросов забирает много лишних ресурсов

  Ответить  
 
 автор: Sfinks   (19.05.2012 в 15:33)   письмо автору
 
   для: 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 |
+---------+----+

  Ответить  
 
 автор: pavluxa09   (19.05.2012 в 21:16)   письмо автору
 
   для: Sfinks   (19.05.2012 в 15:33)
 

А это будет меньше ресурсов кушать?

  Ответить  
 
 автор: cheops   (19.05.2012 в 21:23)   письмо автору
 
   для: pavluxa09   (19.05.2012 в 21:16)
 

Прогоните оба запроса через EXPLAIN и выложите результаты (очень сильно все зависит от объема таблиц и ключей).

  Ответить  
 
 автор: pavluxa09   (20.05.2012 в 11:23)   письмо автору
 
   для: 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

  Ответить  
 
 автор: cheops   (20.05.2012 в 21:51)   письмо автору
 
   для: pavluxa09   (20.05.2012 в 11:23)
 

Первый запрос использует временную таблицу на жестком диске, второй её вроде как не использует, но зато перебирает больше столбцов, вообще бы индексы нужно вводить. Однако, если у вас будет 3 записи - все-равно какой запрос, все будет быстро работать.

  Ответить  
 
 автор: pavluxa09   (21.05.2012 в 14:53)   письмо автору
 
   для: cheops   (20.05.2012 в 21:51)
 

а если будет около милиона?

  Ответить  
 
 автор: cheops   (21.05.2012 в 16:45)   письмо автору
 
   для: pavluxa09   (21.05.2012 в 14:53)
 

Будет плохо, впрочем, если у вас будут такие объемы, я бы порекомендовал бы вам время от времени осуществлять подсчет количеств по cron-заданию (внешнему или MySQL) и складировать их в отдельную таблицу, откуда данные и извлекать по мере надобности (особенно, если этот запрос будет выполняться довольно часто).

  Ответить  
 
 автор: pavluxa09   (21.05.2012 в 19:09)   письмо автору
 
   для: cheops   (21.05.2012 в 16:45)
 

Понял. Спасибо.

  Ответить  
 
 автор: Sfinks   (25.05.2012 в 01:55)   письмо автору
 
   для: 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

  Ответить  
 
 автор: pavluxa09   (25.05.2012 в 11:44)   письмо автору
 
   для: Sfinks   (25.05.2012 в 01:55)
 

Спасибо, сейчас сделаем!

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования