нужно подсчитать кол-во уникальных distr_id в запросе:
SELECT COUNT(DISTINCT distr_id) FROM mytable where game_id=33 AND distr_id>=44 ORDER BY distr_id;
этот запрос работает как надо за одним исключением — долго.
долго, я думаю, потому, — происходит реальный селект всех distr_id, и потом к ним применяется DISTINCT и только потом — COUNT().
индексы для game_id и distr_id созданы.
вопрос в том, как ускорить?
спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Maniacal, Вы писали:
M>Некоторые люди пишут, что иногда лучше использовать GROUP BY. M>Под рукой нет MySQL, может, стоит попробовать что-нибудь эдакое: M>
M>SELECT count(distr_id) FROM (SELECT distr_id FROM mytable where game_id=33 AND distr_id>=44) GROUP BY distr_id
M>
вот попытался, но получаю такую ошибку: every derived table must have its own alias
я тот еще спец по БД, и не очень понимаю, что нужно поправить в вашем примере...
M>И да. Команда EXPLAIN перед запросом покажет план выполнения и узкие места (FULL SCAN).
ща попробую...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: подсчитать кол-во уникальных значений без селекта
Здравствуйте, niXman, Вы писали:
X>привет!
X>есть такая MySql БД: X>
X>int game_id
X>int distr_id
X>
X>нужно подсчитать кол-во уникальных distr_id в запросе: X>
X>SELECT COUNT(DISTINCT distr_id) FROM mytable where game_id=33 AND distr_id>=44 ORDER BY distr_id;
X>
X>вопрос в том, как ускорить?
Я не знаю, какой у вас PK на этой таблице. В идеале для долго работающих запросов нужен покрывающий индекс, чтобы запрос не обращался к PK вообще и брал всю инфу из индекса.
Можно попробовать ещё так — добавить позапрос, что сократить возврат количества данных, по которому работает distinct:
SELECT COUNT(DISTINCT t1.distr_id)
FROM
( SELECT distr_id
FROM mytable
WHERE game_id=33) AS t1
WHERE t1.distr_id>=44;
И ещё рекомендую проверить фрагментацию ваших индексов.
Re[5]: подсчитать кол-во уникальных значений без селекта
Здравствуйте, niXman, Вы писали:
X>ну и как костыль — могу добавить таблицу, в которой тригером апдейтить кол-во действий для конкретной игры...
глупость написал
мне же нужно не просто знать кол-во действий для игры, но кол-во действий начиная с какого-то конкретного ID`а действия...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: подсчитать кол-во уникальных значений без селекта
Здравствуйте, Milena, Вы писали:
M>Я не знаю, какой у вас PK на этой таблице. В идеале для долго работающих запросов нужен покрывающий индекс, чтобы запрос не обращался к PK вообще и брал всю инфу из индекса.
РК — id, тут он вообще не используется...
M>Можно попробовать ещё так — добавить позапрос, что сократить возврат количества данных, по которому работает distinct:
M>
M>SELECT COUNT(DISTINCT t1.distr_id)
M>FROM
M>( SELECT distr_id
M> FROM mytable
M> WHERE game_id=33) AS t1
M>WHERE t1.distr_id>=44;
M>
да, для distinct сократит, но при этом селектит все distr_id для конкретной игры, коих миллионы...
т.е. этот способ самый долгий...
M>И ещё рекомендую проверить фрагментацию ваших индексов.
это что?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали: X>думаете, есть смысл пробовать?
Зависит от количества различных game_id в таблице.
Если их, скажем, 2, то такой индекс всего лишь уполовинит время работы запроса.
А если их миллион — то и работать будет в миллион раз быстрее.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: подсчитать кол-во уникальных значений без селекта
Здравствуйте, niXman, Вы писали:
X>>ну и как костыль — могу добавить таблицу, в которой тригером апдейтить кол-во действий для конкретной игры... X>глупость написал X>мне же нужно не просто знать кол-во действий для игры, но кол-во действий начиная с какого-то конкретного ID`а действия...
Можно добавить вспомогательную таблицу следующей структуры:
SELECT game_id, distr_id DIV 1000 AS distr_range, COUNT(game_id) AS count FROM mytable GROUP BY game_id, distr_range;
Триггером поддерживать её согласованность с основной таблицей. Исходный запрос разбивается на две части — одна часть работает по неполному диапазону distr_id из исходной таблицы, а вторая — суммирует все полные диапазоны из вспомогательной. Таким образом вместо одного запроса на миллионы записей будет два запроса на тысячи.
Re[7]: подсчитать кол-во уникальных значений без селекта
Здравствуйте, Sergei MO, Вы писали:
SM>Можно добавить вспомогательную таблицу следующей структуры: SM>
SM>SELECT game_id, distr_id DIV 1000 AS distr_range, COUNT(game_id) AS count FROM mytable GROUP BY game_id, distr_range;
SM>
SM>Триггером поддерживать её согласованность с основной таблицей. Исходный запрос разбивается на две части — одна часть работает по неполному диапазону distr_id из исходной таблицы, а вторая — суммирует все полные диапазоны из вспомогательной. Таким образом вместо одного запроса на миллионы записей будет два запроса на тысячи.
это просто великолепно!
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[8]: подсчитать кол-во уникальных значений без селекта