Правильно ли сканировать таблицу в MySQL, используя «SELECT * .. LiMIT start, count» без предложения ORDER BY? - PullRequest
0 голосов
/ 07 декабря 2010

Предположим, таблица X содержит 100 кортежей.

Будет ли следующий подход к сканированию X генерировать все кортежи в TABLE X, в MySQL?

for start in [0, 10, 20, ..., 90]:
    print results of "select * from X LIMIT start, 10;"

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

Мне нужно отсканировать каждый кортеж в таблице в приложении, и я хочу, чтобы это делалось без использования слишком большого количества памяти в приложении (так что просто выполнить «выбор * из X» не удалось).

Ответы [ 2 ]

3 голосов
/ 07 декабря 2010

Нет, это не безопасное предположение. Без предложения ORDER BY нет гарантии, что ваш запрос будет возвращать уникальные результаты каждый раз. Если эта таблица правильно проиндексирована, добавление ORDER BY (для индекса) не должно быть слишком дорогим.

Редактировать: Не- ORDER BY ed результаты будут иногда в порядке кластерного индекса, но я бы не стал вкладывать деньги в это!

1 голос
/ 07 декабря 2010

Если вы используете таблицы таблиц Innodb или MyISAM, лучше использовать интерфейс HANDLER. Только MySQL поддерживает это, но делает то, что вы хотите:

http://dev.mysql.com/doc/refman/5.0/en/handler.html

Кроме того, MySQL API поддерживает два режима получения данных с сервера:

  1. сохранить результат: в этом режиме, как только выполняется запрос, API получает весь набор результатов перед возвратом к пользовательскому коду. Это может использовать много результатов буферизации памяти клиента, но сводит к минимуму использование ресурсов на сервере.
  2. использовать результат: в этом режиме API выводит результаты построчно и чаще возвращает управление пользовательскому коду. Это минимизирует использование памяти на клиенте, но может дольше удерживать блокировки на сервере.

Большинство API MySQL для разных языков поддерживают это в той или иной форме. Обычно это аргумент, который можно указать, например, при создании соединения, и / или отдельный вызов, который можно использовать для существующего соединения, чтобы переключить его в этот режим.

Итак, в ответ на ваш вопрос - я бы сделал следующее:

set the connection to "use result" mode;
select * from X
...