Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте.
Помогите, пожалуйста, написать оптимальный с точки зрения скорости выполнения запрос на выборку строки из таблицы.
В таблице есть несколько столбцов: id, дата и прочие. В этой таблице несколько десятков тысяч записей.
Нужно найти последнюю запись к указанной дате. Поясню: Пользователь вводит дату. Например, 1 Августа такого-то года.
Нужно, чтобы были найдена либо последняя запись для данного дня (т.е. если в этом дне много записей, то взять запись с наибольшим id), либо, если за текущий день нету записей - за самый ближайший предыдуший день, в котором есть записи.
Неактивен
p.s.
Ну, у меня допустим так:
Неактивен
Все правильно, если не устроит быстродействие можно добавить индекс по дате (скорее всего нужно).
Но это будет верно работать только если ID идут по возрастанию.
Отредактированно klow (06.08.2017 08:53:03)
Неактивен
klow написал:
Все правильно, если не устроит быстродействие можно добавить индекс по дате (скорее всего нужно).
А как это делается?
klow написал:
Но это будет верно работать только если ID идут по возрастанию.
Автоинкрементом, но многие строки удалены. Но всё равно всегда по возрастанию.
Неактивен
inmerdorm написал:
А как это делается?
inmerdorm написал:
Автоинкрементом, но многие строки удалены. Но всё равно всегда по возрастанию.
Удаление - не страшно.
Неактивен
klow, спасибо за ответ.
Кол-во строк:
Без индекса:
С индексом:
Говорит ли результат о том, что я зазря заморачиваюсь?
p.s. какой движок должен быть для такой таблицы? я когда её сто лет назад создавал, выбрал InnoDB по неглубокому анализу гугловыдачи. Однако я, как не специалист, не уверен в своём выборе.
Отредактированно inmerdorm (06.08.2017 15:19:07)
Неактивен
В данном случае это время не выборки данных, а результата EXPLAIN.
Индекс рекомендуется, но полный ответ зависит и от других условий. Например, если это выборка будет раз в день и ее время не существенно, тогда можно и без индекса, для экономии (сомнительной) места на диске. Но я бы не заморачивался и делал бы индекс.
InnoDB - выбор правильный для большинства случаев.
Отредактированно klow (07.08.2017 13:59:37)
Неактивен
Со скоростью пули тут бы отработал индекс на связку (`date`,`id`),
но, увы, полностью индекс будет задействован только если будет условие равенства на `date`, а не <=.
Неактивен
но, увы, полностью индекс будет задействован только если будет условие равенства на `date`, а не <=.
Думаю будет, и второй рисунок тому подтверждение. Может имелось ввиду DATETIME?
Отредактированно klow (08.08.2017 14:07:49)
Неактивен
Если ТС приведет explain'ы на запросы
Неактивен
klow написал:
но, увы, полностью индекс будет задействован только если будет условие равенства на `date`, а не <=.
Думаю будет, и второй рисунок тому подтверждение. Может имелось ввиду DATETIME?
нет, просто date.
deadka написал:
Если ТС приведет explain'ы на запросы
SELECT * FROM `table1` where `date` <= '2014-01-03' ORDER BY `id` DESC LIMIT 1;
иSELECT * FROM `table1` where `date` = '2014-01-03' ORDER BY `id` DESC LIMIT 1;
то мы должны увидеть разницу .
klow написал:
В данном случае это время не выборки данных, а результата EXPLAIN.
Да всё равно ноль показывает.
Отредактированно inmerdorm (09.08.2017 00:38:17)
Неактивен
deadka написал:
Со скоростью пули тут бы отработал индекс на связку (`date`,`id`),
но, увы, полностью индекс будет задействован только если будет условие равенства на `date`, а не <=.
Я говорю про использование индекса именно на связку (date,id). Что он будет использоваться полностью и работать очень быстро - в случае если на дату будет строгое, а не нестрогое равенство.
А приведенный explain использует PRIMARY KEY, подозреваю, это на поле id.
Неактивен
делать связанный индекс, бессмысленно, так как уже есть индекс на ID. Достаточно только по date.
Неактивен
klow написал:
делать связанный индекс, бессмысленно, так как уже есть индекс на ID. Достаточно только по date.
Два индекса одновременно использоваться не будут, здесь не PostgreSQL . Так что вполне осмысленно.
Но разница в скорости будет заметна только на больших объемах данных, и если много id соответствует одной дате.
Неактивен
Понятно, что в данной выборке не будут использоваться два индекса, но существовать в базе будут два индекса на основе одного поля. В этом нет смысла. Возможно, это имеет смысл только на очень больших объемах, но в данном случае это бессмысленно. Есть индекс по ID и достаточно по DATE, делать индекс составной (DATE, ID) нет никакого смысла в таком случае.
Неактивен