Индексы при группировке. Подскажите чайнику.

zerkms

TDD infected
Команда форума
MuXaJIbI41981
пожалуйста:
Код:
mysql> EXPLAIN SELECT COUNT(*), `obj_id` FROM `sys_access` WHERE `obj_id` > 666 GROUP BY `obj_id`;
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+--------------------------+
| id | select_type | table      | type  | possible_keys         | key        | key_len | ref  | rows | Extra                    |
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | sys_access | range | obj_id_gid,obj_id_uid | obj_id_uid | 5       | NULL |   63 | Using where; Using index |
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT COUNT(`id`), `obj_id` FROM `sys_access` WHERE `obj_id` > 666 GROUP BY `obj_id`;
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+-------------+
| id | select_type | table      | type  | possible_keys         | key        | key_len | ref  | rows | Extra       |
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+-------------+
|  1 | SIMPLE      | sys_access | range | obj_id_gid,obj_id_uid | obj_id_uid | 5       | NULL |   63 | Using where |
+----+-------------+------------+-------+-----------------------+------------+---------+------+------+-------------+
1 row in set (0.00 sec)
 

zerkms

TDD infected
Команда форума
findnext
уже прибавил.
может уймётесь и пойдёте учить английский и читать документацию внимательнее?

-~{}~ 27.02.09 19:51:

кстати во втором запросе всё случайно уместилось в память (как видно - 63 ряда всего). если изменить в обоих запросах > на <, то Extra первого не изменится, а во втором появится:
Using where; Using temporary; Using filesort
 

Фанат

oncle terrible
Команда форума
да, действительно.
я добрался до эксплейна и он мне тоже показал индекс.
 

findnext

Новичок
zerkms
тогда такой вопрос, а если ипользовать JOIN таблиц. Всегда ли оправдано использовать COUNT(*), или всётаки нужно использовать COUNT(id) ?
 

MuXaJIbI41981

Новичок
zerkms

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

EXPLAIN SELECT COUNT(`obj_id`), `obj_id` FROM `sys_access` WHERE `obj_id` > 666 GROUP BY `obj_id`;

просто самому интересно стало.

а то что я написал говорилось на highload каком то если я не ошибаюсь
 

zerkms

TDD infected
Команда форума
то же самое, что и со *, конечно же.

-~{}~ 27.02.09 20:03:

findnext
Всегда ли оправдано использовать COUNT(*), или всётаки нужно использовать COUNT(id)
count(поле) нужно тогда, когда ты считаешь число записей, в которых поле IS NOT NULL. в остальных случаях - используй *.
 

fixxxer

К.О.
Партнер клуба
zerkms

Не всегда, хотя в данном случае ты прав. В случае с InnoDB, count(*) нельзя взять из дескриптора таблицы, т.к. он зависит от текущей транзакции, и select count(id) from table (на id есть индекс) будет быстрее count(*).
 

findnext

Новичок
спасибо за просветление, я считал что достаточно хорошо разбираюсь в sql но видимо это не так...
 

fixxxer

К.О.
Партнер клуба
findnext

Рекомендую изучить сайт mysqlperformanceblog.com. Узнаешь много нового :)
 

zerkms

TDD infected
Команда форума
В случае с InnoDB, count(*) нельзя взять из дескриптора таблицы, т.к. он зависит от текущей транзакции, и select count(id) from table (на id есть индекс) будет быстрее count(*).
а вот этого не знал - с иннодб экспериенса почти 0.
%)
 

findnext

Новичок
select count(id) from table (на id есть индекс) будет быстрее count(*).
а у меня именно так и сделано, гыгыгы, значит не придётся переписывать запросы, вот как бывает, делаешь по теории неправильно а получается правильно на практике :D:D:D

-~{}~ 27.02.09 13:20:

fixxxer
спасибо, ща я бы напереписывал запросов...
 

korchasa

LIMB infected
Автор оригинала: fixxxer
Не всегда, хотя в данном случае ты прав. В случае с InnoDB, count(*) нельзя взять из дескриптора таблицы, т.к. он зависит от текущей транзакции, и select count(id) from table (на id есть индекс) будет быстрее count(*).
Эрм, если * нельзя взять из дескриптора, то почему можно взять id? Разве при * в данном случае будет использоваться не PRIMARY KEY? Тогда на живой базе у них и данные будут разные?
 
Сверху