Задавайте вопросы, мы ответим
Вы не зашли.
Есть с виду простейшая задача, которую не могу решить.
Есть таблица, 3 колонки. Нужно выбрать срез по времени и сгруппировать по колонке hash. Проблема в том, что если используется ключ hash, то перебираются все записи, вне зависимости от среза по времени. Если использовать составной индекс (ctime, hash), то используется только часть индекса + создается временная таблица.
В итоге нужно сделать группировку по срезу времени без использования временной таблицы (Using temporary). Увы, у меня не получается
Неактивен
Выбирать здесь данные "чисто" по индексу не получится при такой постановке задачи.
Если бы выбирали WHERE `ctime` = 1490979600 GROUP BY `hash`, то хорошо бы себя повел составной индекс (`ctime`,`hash`). Но тут условие < > - так что вторая часть индекса не будет использоваться.
В итоге нужно сделать группировку по срезу времени без использования временной таблицы
А что значит нужно? Кому нужно? Расскажите подробнее. Иначе задача нерешаема. Единственное, что приходит в голову (это если у Вас детерменированные интервалы на ctime, допустим, в пределах дня) - добавить еще одно денормализованное поле, которое содержит дату, или час или еще что - и с ним уже построить составной индекс.
А при текущем запросе по хорошему нужно использовать индекс по полю ctime и это будет оптимально. Можно подсказать оптимизатору, чтобы он его и использовал ( use index, force index, ignore index )
Неактивен
deadka написал:
А что значит нужно? Кому нужно? Расскажите подробнее. Иначе задача нерешаема.
В таблице порядка 20 млн записей. В выборку за день попадает примерно 60к записей
deadka написал:
А при текущем запросе по хорошему нужно использовать индекс по полю ctime и это будет оптимально. Можно подсказать оптимизатору, чтобы он его и использовал ( use index, force index, ignore index )
Либо используется индекс по полю ctime, но из-за группировки перебираются все записи. Либо же наоборот, группировка работает по индексу, но вот временной срез по ctime перебирает все записи.
Неактивен
>Либо используется индекс по полю ctime, но из-за группировки перебираются все записи.
Не все, а только те, что выбраны по индексу.
Покажите explain запроса.
Неактивен
deadka написал:
>Либо используется индекс по полю ctime, но из-за группировки перебираются все записи.
Не все, а только те, что выбраны по индексу.
Покажите explain запроса.
Неактивен
К сожалению, в жизни нету магии. Индекс — это аналог телефонного справочника, где hash — имя человека, а ctime — его телефоны. И аналог Вашего запроса — «покажите мне все телефоны людей, сгруппированных по имени, телефоны которых начинаются с +7495».
Вы можете или держать книгу сортированных имен (и тогда вынуждены внутри имен полным сканом смотреть телефоны), или иметь книгу всех телефонов (и тогда вынуждены внутри нужного диапазона телефонов отдельно выписывать имена пользователей).
Что делать? Пересмотреть задачу. Я бы думал в сторону денормализации.
Идея раз. Почти наверняка Вам нужны не любые диапазоны ctime, а только некоторые. Тогда можно сделать отдельную табличку с hash, попадающую в нужные диапазоны.
Идея два. Почти наверняка многие hash приходят только раз, а потом больше не участвуют в игре. Тогда можно сделать табличку (hash, min_ctime, max_ctime) и проверять заранее, попадает ли хэш в принципе в диапазон. А для найденных hash уже проверять честные вхождения по большой таблице.
Неактивен
paulus написал:
Вы можете или держать книгу сортированных имен (и тогда вынуждены внутри имен полным сканом смотреть телефоны), или иметь книгу всех телефонов (и тогда вынуждены внутри нужного диапазона телефонов отдельно выписывать имена пользователей).
Да, вот об этом я и говорил, что Или Или.
paulus написал:
Что делать? Пересмотреть задачу. Я бы думал в сторону денормализации.
Идея раз. Почти наверняка Вам нужны не любые диапазоны ctime, а только некоторые. Тогда можно сделать отдельную табличку с hash, попадающую в нужные диапазоны.
Идея два. Почти наверняка многие hash приходят только раз, а потом больше не участвуют в игре. Тогда можно сделать табличку (hash, min_ctime, max_ctime) и проверять заранее, попадает ли хэш в принципе в диапазон. А для найденных hash уже проверять честные вхождения по большой таблице.
В принципе, я ожидал, что решений в "одну" строчку не будет. Ваши идеи весьма привлекательны, спасибо за подсказку!
Тему считаю закрытой.
Неактивен