MySQL Select эффективный первый и последний ряд

Я хочу получить две строки из моей таблицы в базе данных 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, но тогда мне все равно пришлось бы дважды заказывать несортированный список, чего я также хочу избежать, потому что вторая сортировка выполняется точно так же, как и первая

Я хотел бы заказать один раз, а затем выбрать первое и последнее значение этого упорядоченного списка, но я не знаю более эффективного способа, чем тот, с двумя запросами. Я знаю, что выигрыш в производительности не будет гигантским, но, тем не менее, я знаю, что списки растут и по мере того, как они становятся все больше и больше, и я выполняю эту часть для некоторых таблиц, мне нужен наиболее эффективный способ сделать это.
Я нашел пару похожих тем, но ни одна из них не затрагивала этот конкретный вопрос о производительности.

Любая помощь высоко ценится.

1

Решение

(Это и «ответ», и опровержение ошибок в некоторых комментариях.)

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, который вы получите, будет непредсказуемым.

1

Другие решения

Ваши вопросы в порядке. То, что вы хотите, это индекс на worktime(dateTimeBegin), MySQL должен быть достаточно умным, чтобы использовать этот индекс для ASC а также DESC сорта. Если вы проверите это, а это не так, то вам понадобятся два индекса: worktime(dateTimeBegin asc) а также worktime(dateTimeBegin desc),

Запускаете ли вы один или два запроса, зависит от вас. Один запрос (связан UNION ALL) немного более эффективен, потому что у вас есть только одно обращение к базе данных. Тем не менее, два могут легче вписаться в ваш код, и разница в производительности не важна для большинства целей.

2

По вопросам рекламы [email protected]