Как запросить фиксированное количество строк, упорядоченных по дате в MySQL?

0

Я использую mysql для запроса БД. Я хотел бы запросить НЕ полную базу данных, а только последние 1000 строк, упорядоченных по метке времени.

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

select * from mutable where name = 'myschema' ORDER BY start_time DESC LIMIT 1000;

Любая помощь?

  • 0
    То, что вы ищете, возможно, только если вы дадите ему условие, например WHERE start_time > some_number . MySQL не может знать, что такое «последние 1000 строк, упорядоченные по метке времени», если он не упорядочивает строки по значению (полное сканирование таблицы), а затем принимает 1000.
  • 0
    В чем разница между «вернуть фиксированное количество выбранных элементов», которое вам не нужно, и «запросить фиксированное количество элементов», которое вы хотите. Вы можете объяснить это лучше? Вы намерены использовать это как подзапрос, и вы надеетесь исключить полное сканирование таблицы или есть что-то еще, к чему вы стремитесь? Если это вопрос оптимизации / подзапроса, то вы можете прочитать о том, как mysql оптимизирует ORDER BY ... LIMIT, используя индексы и тому подобное.
Показать ещё 2 комментария
Теги:
query-performance

2 ответа

0

tl; dr Сортировать меньше данных

Я предполагаю, что ваша mutable таблица имеет автоинкрементный первичный ключ mutable.mutable_id.

Затем вы можете сделать это:

                 SELECT mutable_id FROM mutable 
                  WHERE name = 'myschema' 
                  ORDER BY start_time DESC 
                  LIMIT 1000;

Это дает вам результирующий набор идентификаторов всех соответствующих строк. В этом случае ORDER BY... LIMIT работает только для сортировки mutable_id и start_time, а не всей таблицы. Так что на сервере MySql требуется меньше места и времени.

Затем вы используете этот запрос для получения подробной информации:

 SELECT *
   FROM mutable
  WHERE mutable_id IN (
                 SELECT mutable_id FROM mutable 
                  WHERE name = 'myschema' 
                  ORDER BY start_time DESC 
                  LIMIT 1000
        )
  ORDER BY start_time DESC;

Это позволит получить все необходимые данные без необходимости сканирования и сортировки всей таблицы.

Если вы создадите индекс по name и start_time то подзапрос будет быстрее: запрос может произвольно получить доступ к индексу с соответствующим name, а затем сканировать записи start_time по одной, пока не найдет 1000. Не нужно сортировать; индекс предварительно.

CREATE INDEX x_mutable_start_time ON mutable (name, start_time);

Если вы используете MySQL 8, вы можете создать нисходящий индекс, и это будет еще быстрее.

CREATE INDEX x_mutable_start_time ON mutable (name, start_time DESC);
  • 0
    Подзапрос, который вы используете, выполняет то, что делает исходный запрос OP, почему он будет быстрее, чем исходный запрос?
  • 0
    Мой подзапрос выполняет намного меньше работы, чем исходный запрос. (1) Он не сортирует всю таблицу только для того, чтобы отбросить большинство строк. (2) Он может частично сканировать составной индекс, который я предложил, чтобы избежать этапа сортировки.
Показать ещё 3 комментария
0

Это работает только с auto_increment

Хитрость заключается в сортировке меньшего количества данных, как упоминал О. Джонс. Проблема в том, чтобы рассказать MySQL, как это сделать.

MySQL не может знать, что такое "последние 1000 записей", если не сортирует их по запросу. Это именно то, чего вы хотите избежать, поэтому вам нужно указать MySQL, как найти "последние 1000 записей".

Этот трюк состоит в сообщении MySQL, с какого параметра auto_increment начинать поиск данных. Проблема в том, что вы используете временные метки, поэтому я не уверен, подходит ли это для вашего конкретного случая использования.

Вот запрос:

SELECT * FROM mutable 
WHERE 'name' = 'myschema' 
AND id > (SELECT MAX(id) - 1000 FROM mutable WHERE 'name' = 'myschema') 
ORDER BY start_time DESC LIMIT 1000;

Проблемы:

  • auto_increments имеют пробелы. Эти числа не являются последовательными, они уникальны и рассчитываются с помощью алгоритма последовательного приращения. Чтобы получить лучшие результаты, увеличьте число вычитания. Вы можете получить 1000 результатов, но вы можете получить 500 результатов - в зависимости от вашего набора данных

  • если у вас нет auto_increment, это бесполезно

  • если введенные временные метки необходимо предварительно отсортировать от большего к меньшему, это бесполезно

Преимущества: - первичный ключ используется для определения диапазона значений (где id> x), поэтому сокращение набора данных будет максимально быстрым.

  • 0
    Еще одна проблема: требуется временная таблица и сортировка.
  • 0
    @RickJames - нет проблем. Естественно, вы не объяснили, как решается несуществующая проблема.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню