Насколько улучшается производительность при использовании LIMIT в предложении SQL? - PullRequest
6 голосов
/ 19 апреля 2011

Предположим, у меня есть таблица в моей базе данных с 1.000.000 записями.

Если я выполню:

SELECT * FROM [Table] LIMIT 1000

Этот запрос займет столько же времени, как если бы у меня была эта таблица с 1000 записями, и просто выполните:

SELECT * FROM [Table]

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

Я сказал 1.000.000 записей, но это может быть 20.000.000. Это был просто пример.

Edit:
Конечно, при использовании LIMIT и без его использования в той же таблице запрос, построенный с использованием LIMIT, должен выполняться быстрее, но я не спрашиваю об этом ...

Чтобы сделать его общим:

Table1: X записей
Table2: Y записей

(X << Y)

То, что я хочу сравнить, это:

SELECT * FROM Table1

и

SELECT * FROM Table2 LIMIT X

Редактировать 2:
Вот почему я спрашиваю:

У меня есть база данных с 5 таблицами и взаимосвязями между некоторыми из них. Одна из этих таблиц будет (я уверен на 100%) содержать около 5.000.000 записей. Я использую SQL Server CE 3.5, Entity Framework в качестве ORM и LINQ to SQL для выполнения запросов.

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

Итак, вопрос возник, потому что я думал о том, чтобы сделать это (ограничение X записей на запрос) или если в базе данных хранятся только X результаты (последние), что потребует некоторого удаления в базе данных, но я просто думал ...

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

Ответы [ 3 ]

4 голосов
/ 19 апреля 2011

TAKE 1000 из таблицы 1000000 записей - будет в 1000000/1000 (= 1000) раз быстрее, потому что нужно только просматривать (и возвращать) 1000/1000000 записей. Поскольку он делает меньше, он, естественно, быстрее.

Результат будет довольно (псевдо-) случайным, так как вы не указали порядок, в котором нужно БРАТЬ. Однако, если вы введете заказ, то одно из двух приведенных ниже станет истинным:

  1. Предложение ORDER BY следует за индексом - приведенное выше утверждение все еще верно.
  2. Предложение ORDER BY не может использовать какой-либо индекс - оно будет только незначительно быстрее, чем без TAKE, потому что
    • он должен проверять ВСЕ записи и сортировать по ORDER BY
    • доставить только подмножество (TAKE count)
    • так что на первом шаге это не быстрее, но на втором шаге меньше ввода-вывода / сети, чем для ВСЕХ записей

Если вы берете 1000 записей из таблицы, состоящей из 1000 записей, это будет эквивалентно (с небольшими существенными различиями) взятию 1000 записей от 1 миллиарда, если вы следите за случаем (1) отсутствия заказа или (2) заказ по индексу

1 голос
/ 19 апреля 2011

Это будет приблизительно линейно, если вы не укажете ни поля, ни порядок, ни все записи.Но это мало что тебе дает.Он разваливается, как только ваш запрос хочет сделать что-то полезное.

Это было бы немного интереснее, если бы вы намеревались сделать какой-то полезный вывод и рассказать нам о том, как он будет использован для создания дизайна.выбор в некотором контексте.

Спасибо за разъяснение.

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

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

В MySQL есть модификаторы LIMIT и OFFSET (начальная запись #), в основном для точной цели создания фрагментов списка для подкачки, как вы описываете.

Это контрпродуктивно - начать думать о разработке схемы и очистке записипока вы не использовали это и кучу других стратегий.В этом случае не решайте проблемы, которых у вас еще нет.Строго говоря, таблицы с несколькими миллионами строк невелики, если они правильно проиндексированы.

1 голос
/ 19 апреля 2011

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

Если X = Y, то очевидно, что они должны работать с одинаковой скоростью, так как механизм запросов будет проходить записи в абсолютно одинаковом порядке - в основном сканирование таблицы- для этого простого оператора SELECT.Не будет никакой разницы в плане запроса.

Если Y> X только немного, то также похожая скорость.

Однако, если Y >> X (то есть Y имеет много-много большестрок, чем X), тогда версия LIMIT МОЖЕТ быть медленнее.Не из-за плана запроса - опять-таки должен быть таким же - но просто потому, что внутренняя структура макета данных может иметь еще несколько уровней.Например, если данные хранятся в виде листов на дереве, может быть больше уровней дерева, поэтому для доступа к тому же количеству страниц может потребоваться немного больше времени.

Другими словами, может быть сохранено 1000 строк.скажем, в 1 уровне дерева в 10 страницах.1000000 строк могут храниться в 3-4 уровнях дерева на 10000 страницах.Даже если взять только 10 страниц из этих 10000 страниц, механизм хранения все равно должен пройти через 3-4 уровня дерева, что может занять немного больше времени.

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

...