o_O. Простейший селект :(

cDLEON

Онанист РНРСlub
:confused:. Простейший селект :(

[sql]
CREATE TABLE `movies` (
`id` bigint(20) NOT NULL auto_increment,
`dirId` int(11) NOT NULL,
`movieName` varchar(40) collate utf8_bin default NULL,
`description` text collate utf8_bin NOT NULL,
PRIMARY KEY (`id`),
KEY `dirId` (`dirId`)
) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=17 ;
[/sql]
[sql]
EXPLAIN SELECT * FROM grabber_movies GROUP BY dirId
[/sql]
PHP:
 id  	 select_type  	 table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
1  	SIMPLE  	grabber_movies  	ALL  	NULL  	NULL  	NULL  	NULL  	16  	Using temporary; Using filesort
 

cDLEON

Онанист РНРСlub
Бггг...
Я думал и так понятно будет (
Запрос не использует индекс dirId :(
 

Gas

может по одной?
на 16-ти записях быстрее fullscan, что mysql и делает.
 

cDLEON

Онанист РНРСlub
PHP:
1  	SIMPLE  	grabber_movies  	ALL  	NULL  	NULL  	NULL  	NULL  	2575  	Using temporary; Using filesort
Добавил записей...
 

.des.

Поставил пиво кому надо ;-)
1.
CREATE TABLE movies
EXPLAIN SELECT * FROM grabber_movies

2. Что должен делать этот запрос? Использование группировки в сочетании с SELECT * для меня выглядит бесмысленным.
 

cDLEON

Онанист РНРСlub
мне нужно получить по одному мувику из каждой категории.

-~{}~ 01.08.08 19:41:

[sql]
EXPLAIN SELECT d.*,m.* FROM grabber_dirs as d LEFT JOIN grabber_movies as m ON m.dirId=d.id GROUP BY m.dirId
[/sql]
PHP:
1  	SIMPLE  	d  	ALL  	NULL  	NULL  	NULL  	NULL  	3  	Using temporary; Using filesort
1 	SIMPLE 	m 	ref 	dirId 	dirId 	4 	movie_grabber.d.id 	5
Вроде норм, только вот запрос 0.15 сек работает (((

-~{}~ 01.08.08 19:45:

Вопрос, кстати, не снят по поводу первого запроса... =))
 

.des.

Поставил пиво кому надо ;-)
Угу.. вот поэтому и плохо когда первый опыт с SQL приходит через MySQL.
По одному "мувику" из каждой категории это неправильный вопрос. Какому "мувику"? - последнему, самому популярному, и т.д.
Группируя по dirId вы должны использовать аггрегатные функции для всех полей не перечисленных в group
А ваша задача сводится к классическим top x for each category.
И самым быстрым решением будет денормализация и держать в отдельной таблице этот самый "мувик".

по поводу первого запрос вопрос снят, так как субд вообще не должна его обрабатывать.
 

Gas

может по одной?
Вопрос, кстати, не снят по поводу первого запроса...
что касается смысла самого запроса, то .des. правильно говорит о том что этого лучше не хотеть, не знаток в различных субд, но afaik postgres, mssql, oracle такой запрос не дадут выполнить. Mysql разрешает пока, но может в 6-ой версии сделают по умолчанию sql_mode=ONLY_FULL_GROUP_BY, как например и register_globals=off в php.

Если рассуждать почему не используется индекс.
Имхо, запрос предполагает чтение полностью всех данных таблицы. При использовании индекса - чтение данных будет происходить в случайном порядке (в порядке записей в индексе) и это чревато большим количеством операций IO (самое тормозное место обычно) по сравнению c последовательным чтением. Группировка 2.5K елементов в памяти вещь менее тормозная чем чтение этих данных с диска.
Хотя mysql мог бы делать и оптимизацию: сравнивать селективность индекса с общим количеством рядов, и если групп в разы меньше, то идти по индексу, читая только по одной строке данных (конечно будет считана не строка, а блок в N килобайт) для группы, всё равно не важно какие данные в этом случае :)
Но это всё лишь мои предположения.
Заставить использовать индекс можно с помощью force index(`index_name`)

[update]
выполнил несколько запросов на различных табличках,
запросы select * from `table`group by `field`, именно такой запрос понимается под "без force index".
На `field` во всех случаях был ключ.
Для проверки скорости с index сканом и без, форсировался индекс если explain говорил all или ignore index , если type=index:

1. таблица myisam ~700K записей, cardinality: 40000, Row_format=fixed.

a) без force index
time: 2 sec
explain: type=ALL; Using temporary; Using filesort

б) с force index()
time: 5.5 sec
explain: type=index

2. таблица myisam, 4M записей, cardinality: 20000, Row_format=fixed

a) без force index
time: 2 min 52 sec
explain: type=ALL, Using temporary, Using filesort
(добавление order by null и исчезновение Using filesort на скорость никак не влияло).

б) c force index
time: 56 sec
explain: type=index

3. таблица innodb, структура и данные аналогичные пункту 2

a) без force index
time: 1 min 13 sec
explain: type=index

б) c ignore index (чтоб был скан без индекса)
time: 3 min 35 sec
explain: type=ALL, Using temporary, Using filesort

4. запустил такие же тексты на innodb табличках 60K и 500K, всегда mysql предпочитал использовать индекс (и при его использовании запрос выполнялся быстрее) в отличие от myisam, видимо делается предположение что данные могут быть pool_buffer'е.
 
Сверху