[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Помогите придумать запрос:
GET
Помогите придумать запрос:

есть таблица с 1 000 000 записей:
CREATE TABLE IF NOT EXISTS `tab` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_t` int(11) NOT NULL,
`id_z` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_z` (`id_t`,`id_z`)
)
ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1921550 ;


в id_t значения от 1 до 10 000
в id_z от 1 до 100 000

есть запрос:
SELECT id_z, COUNT( * ) AS `cou` 
FROM `tab`
WHERE (
tab.id_t =1
OR tab.id_t =2)
GROUP BY `id_z`
ORDER BY `cou` DESC


Этот запрос использует:
EXPLAIN: Extra Using where; Using index

Можно как то избежать GROUP BY?

Типа такого варианта только правильного:
(if(cou)cou=cou+1 else 1)) AS cou

чтоб он не создавал строчку с таким же id_z а дописывал +1 в столбец счетчик уже существующий?

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
S.Chushkin
Цитата (ABC @ 18.02.2013 - 07:13)
Можно как то избежать GROUP BY?

А зачем? Какова цель этого?

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
SlavaFr
Тяжело дать совет не зная как таблица применяется, а название таблицы и ее полей не очем не говорит.
Судя из того, что ты описал, тебе нужно зделать unique или primary key на (`id_t`,`id_z`) и сделать поле "counter" в котором ты будеш инкрементировать число в случае если поле строка с (`id_t`,`id_z`) уже имеется.
Миграцию в таблицу ты можеш произвести используя SQL который ты привел выше.

_____________
↓↓↓↓↓↓↓↓↓↓
ответ может быть здесь
или в mysql_error();
bestxp
deleted
GET
S.Chushkin

Цель чтоб сделать его быстрее.

SlavaFr

Просто не могу придумать преем...в php бы мог сходу набрасать.
Цитата
и сделать поле "counter"


Вот я и подумал есть ли возможность сделать такое псевдо поле `cou` через AS.

Т.е. если WHERE сработало то в `cou` заносим cou=cou+1; и тогда не надо бужет делать GROUP BY по id_z, а можно сразу будет сделать ORDER BY `cou`

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
SlavaFr
Ну так сделай такую денормализацию создав поле `count`.

ОТ: Давай нормальные названия таблицам и полям, так как потом не только другие, но и ты сам не поймеш их значение.
Помежет тебе название таблицы `tab` если и так понятно, что это таблица?
Вспомниш ли ты сам что означает id_t и id_z или `cou` через 2 месяца?

создавая такие имена, ты не выигрываеш не во времени не в скорости.


_____________
↓↓↓↓↓↓↓↓↓↓
ответ может быть здесь
или в mysql_error();
GET
SlavaFr

Таблица намного сложнее...я тестирую более простой вариант поэтому такие названия.

Добавил count колонку пустую int

SELECT id_z, cou=cou+1 AS `cou` 
FROM `tab`
WHERE (
tab.id_t =1
OR tab.id_t =2)
ORDER BY `cou` DESC


чего то не хочет

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
S.Chushkin
Цитата (ABC @ 18.02.2013 - 12:48)
S.Chushkin
Цель чтоб сделать его быстрее.

Во-первых, Вы не понимаете как работает GROUP BY. Без него алгоритм запроса будет совсем другой (в данном случае).
Во-вторых, в общем случае - сделать можно, но принципиально быстрее не будет.

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
GET
Цитата
Во-первых, Вы не понимаете как работает GROUP BY. Без него алгоритм запроса будет совсем другой (в данном случае).


GROUP BY собирает в кучки и в них в этих маленьких табличках считает строчки.

Без него никаких кучек не будет просто будет еще один столбец cou в котором и будет количество строчек из первого варианта.

Разве нет?

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
S.Chushkin
Цитата (ABC @ 18.02.2013 - 14:33)
GROUP BY собирает в кучки и в них в этих маленьких табличках считает строчки.

Почти.
Ээээ... Этот параметр даёт команду движку группировать записи по указанным параметрам (как правило, полям). Как это делается внутри, не суть важно (хотя, никаких "кучек" там нет). Важно то, что на выходе получится таблица где данные по параметрам группировки будут уникальны (у Вас - id_z). В процессе группировки, движок может выполнить некие команды, например агрегирующие функции count(), sum() и т.п.
В частности, ваш первый запрос выдаст список уникальных id_z и количество записей с этим уникальным id_z. Одинаковых id_z в Вашем варианте может быть множество.
В случае, если убрать GROUP BY, то никакой группировки не будет, естественно. Т.е. если у вас будет миллион id_z = 1, то Вы получите список в миллион записей, а с GROUP BY список с одно записью.

Вообще, SQL придумали англоговорящие так, чтобы он читался как предложение/команда.
Например, Ваш запрос можно "перевести" примерно так:
Выбери все записи из таблицы tab где id_t =1 или id_t =2, сгруппируй их по id_z и подсчитай количество записей в каждой группе, затем упорядочь полученный список по количеству.
Выбрасываем из этого "сгруппируй" и ... получаем другую команду.

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
GET
S.Chushkin

Спасибо.

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
S.Chushkin
А вообще, если конечная цель не избавиться от group by, а просто "ускорить" получение данных, то решается просто.
В таблице, где id_z уникально (наверняка такая есть) добавить поле `count_in_tab`.
На таблицу tab повесить тригер, который будет +/-1 в это поле при каждом изменении. Изменения делать в транзакционных рамках, естественно.

Или добавить доп.таблицу, если нельзя первичную менять или по каким-то другим причинам.

Тогда запрос для получения количеств будет очень быстрым.

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
GET
S.Chushkin

Огромное спасибо за триггеры...я даже не знал про них! Прочитал! Супер! Упрощу админку.

Цитата
Тогда запрос для получения количеств будет очень быстрым.


К сожалению способ не подойдет...эти количества будут всегда разные т.к. эти цифры номера тегов таблицы-словаря и их количество может менятся т.е. 1,2 ... 5
Цитата
tab.id_t =1
OR tab.id_t =2)


зависит от запроса.

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
S.Chushkin
Цитата (ABC @ 18.02.2013 - 16:38)

К сожалению способ не подойдет...эти количества будут всегда разные т.к. эти цифры номера тегов таблицы-словаря и их количество может менятся т.е. 1,2 ... 5
Цитата
tab.id_t =1
OR tab.id_t =2)

зависит от запроса.

Тогда только кеширование спасёт.
Простейший вариант: Попытайтесь добавить в запрос параметр sql_cache (кеширование должно быть включено в настройках движка). Если таблица изменяется много меньше, чем читается, то ускорит заметно.

_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru
GET
S.Chushkin

Спасибо.

_____________
Не тот велик, кто не падал, а тот кто падал и поднимался.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.