Я хочу получить две строки из моей таблицы в базе данных MySQL. эти два ряда должны быть первым и последним после того, как я их заказал. Чтобы добиться этого, я сделал два запроса, эти два:
SELECT dateBegin, dateTimeBegin FROM worktime ORDER BY dateTimeBegin ASC LIMIT 1;";
SELECT dateBegin, dateTimeBegin FROM worktime ORDER BY dateTimeBegin DESC LIMIT 1;";
Я решил не получать весь набор и выбирать первое и последнее в PHP, чтобы избежать, возможно, очень больших массивов. Моя проблема в том, что у меня есть два запроса, и я не знаю, насколько это эффективно. Я хотел объединить их, например, с UNION, но тогда мне все равно пришлось бы дважды заказывать несортированный список, чего я также хочу избежать, потому что вторая сортировка выполняется точно так же, как и первая
Я хотел бы заказать один раз, а затем выбрать первое и последнее значение этого упорядоченного списка, но я не знаю более эффективного способа, чем тот, с двумя запросами. Я знаю, что выигрыш в производительности не будет гигантским, но, тем не менее, я знаю, что списки растут и по мере того, как они становятся все больше и больше, и я выполняю эту часть для некоторых таблиц, мне нужен наиболее эффективный способ сделать это.
Я нашел пару похожих тем, но ни одна из них не затрагивала этот конкретный вопрос о производительности.
Любая помощь высоко ценится.
(Это и «ответ», и опровержение ошибок в некоторых комментариях.)
INDEX(dateTimeBegin)
облегчит SELECT ... ORDER BY dateTimeBegin ASC LIMIT 1
и соответствующий ряд с другого конца, используя DESC
,
MAX(dateTimeBegin)
найду только максимальное значение для этого столбца; будет не непосредственно найдите остальные столбцы в этом ряду. Это потребует подзапроса или JOIN
,
INDEX(... DESC)
— DESC
является игнорируются MySQL. Это почти никогда не является недостатком, так как оптимизатор готов идти в любом направлении через индекс. Дело, где это имеет значение ORDER BY x ASC, y DESC
не могу использование INDEX(x, y)
ни INDEX(x ASC, y DESC)
, Это недостаток MySQL. (Кроме этого, я согласен с «ответом» Гордона.)
( SELECT ... ASC )
UNION ALL
( SELECT ... DESC )
не даст большого, если таковые имеются, преимущества в производительности по сравнению с двумя отдельными выборами. Выберите технику, которая держит ваш Код проще.
Вам почти всегда лучше иметь один DATETIME
(или же TIMESTAMP
) чем разделять DATE
и / или TIME
, SELECT DATE(dateTimeBegin), dateTimeBegin ...
работает просто и «достаточно быстро». Смотрите также функцию DATE_FORMAT()
, Я рекомендую бросить dateBegin
колонка и корректировка кода соответственно. Обратите внимание, что сокращение таблицы может на самом деле ускорить обработку больше, чем стоимость DATE()
, (Разница будет бесконечно мала.)
Без индекса начало с dateTimeBegin
Любой из методов будет медленным и медленным по мере увеличения таблицы. (Я уверен, что это может найти и то и другое MIN()
а также MAX()
только за один полный проход, и сделать это без сортировки. Пара ORDER BYs
взял бы два полных прохода плюс два сорта; 5.6 может иметь оптимизацию, которая почти исключает сортировки.)
Если есть две строки с одинаковым минимумом dateTimeBegin
, который вы получите, будет непредсказуемым.
Ваши вопросы в порядке. То, что вы хотите, это индекс на worktime(dateTimeBegin)
, MySQL должен быть достаточно умным, чтобы использовать этот индекс для ASC
а также DESC
сорта. Если вы проверите это, а это не так, то вам понадобятся два индекса: worktime(dateTimeBegin asc)
а также worktime(dateTimeBegin desc)
,
Запускаете ли вы один или два запроса, зависит от вас. Один запрос (связан UNION ALL
) немного более эффективен, потому что у вас есть только одно обращение к базе данных. Тем не менее, два могут легче вписаться в ваш код, и разница в производительности не важна для большинства целей.