#sql #database #take
#sql #База данных #возьмите
Вопрос:
Предположим, у меня в базе данных есть таблица с 1.000.000
записями.
Если я выполняю:
SELECT * FROM [Table] LIMIT 1000
Займет ли этот запрос столько же времени, как если бы у меня была эта таблица с 1000
записями и я просто выполнял:
SELECT * FROM [Table]
?
Я не ищу, займет ли это точно такое же время. Я просто хочу знать, займет ли выполнение первого намного больше времени, чем второго.
Я сказал 1.000.000
записи, но это могло быть 20.000.000
. Это был просто пример.
Редактировать:
Конечно, при использовании 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 для SQL для выполнения запросов.
Мне нужно выполнить в основном три вида непростых запросов, и я думал о том, чтобы показать пользователю ограничение записей (точно так же, как это делают многие веб-сайты). Если пользователь хочет просмотреть больше записей, у него есть возможность еще больше ограничить поиск.
Итак, вопрос возник, потому что я думал о том, чтобы сделать это (ограничить количество X
записей на запрос) или сохранить в базе данных только X
результаты (последние), что потребует выполнения некоторых удалений в базе данных, но я просто подумал…
Итак, эта таблица может содержать 5.000.000
записи или больше, и чего я не хочу, так это показывать пользователю 1000
или около того, и даже таким образом запрос все равно будет таким же медленным, как если бы он возвращал 5.000.000
строки.
Комментарии:
1. что делает
TAKE
ключевое слово? Я никогда с этим не сталкивался. это синонимLIMIT
?2. @wired00 Извините. Я думал о LINQ : / Я отредактирую это 🙂
3. ОГРАНИЧЕНИЕ касается только MySQL. Вероятно, следует пометить это так.
4. @Stephen я считаю, что LIMIT есть и в PostgresSQL 🙂
5. @wired00: Вы правы,
LIMIT
поддерживается PostgreSQL иTOP
является только TSQL / SQL Server.FETCH FIRST x ROWS ONLY
теперь это ANSI, но DB2 — единственный, кто реализует IIRC
Ответ №1:
TAKE 1000
из таблицы с 1000000 записями — будет в 1000000/1000 ( = 1000
) раз быстрее, потому что для этого нужно всего лишь просмотреть (и вернуть) 1000/1000000 записей. Поскольку он выполняет меньше, он, естественно, быстрее.
Результат будет довольно (псевдо-) случайным, поскольку вы не указали порядок, в котором следует ВЫПОЛНЯТЬ. Однако, если вы вводите порядок, то одно из двух приведенных ниже становится истинным:
- Предложение ORDER BY следует за индексом — приведенное выше утверждение по-прежнему верно.
- Предложение ORDER BY не может использовать какой-либо индекс — это будет лишь незначительно быстрее, чем без TAKE, потому что
- он должен проверять ВСЕ записи и сортировать по
ORDER BY
- доставьте только подмножество (ПРИМИТЕ во внимание)
- таким образом, на первом шаге это не быстрее, но на втором шаге требуется меньше операций ввода-вывода / сети, чем для ВСЕХ записей
- он должен проверять ВСЕ записи и сортировать по
Если вы ВОЗЬМЕТЕ 1000 записей из таблицы из 1000 записей, это будет эквивалентно (с небольшими существенными отличиями) взятию 1000 записей из 1 миллиарда, при условии, что вы соблюдаете случай (1) отсутствия порядка по или (2) порядка по индексу
Комментарии:
1. таким образом, это означает, что если столбец
A
не проиндексирован, и я делаюORDER BY
в этом столбце, запрос к одной и той же базе данных сLIMIT X
и без него будет довольно схожим с точки зрения производительности, потому что для его сортировки потребуется загрузить все данные, а затем вернуть первыеX
записи?2. Быстрее делать что? Если это где-то передает результат, то это ограниченный ввод-вывод, и база данных в значительной степени не имеет значения.
3. @Oscar / Если вы используете
ORDER BY someunindexedcolumn LIMIT X
(или TAKE, или TOP, или FETCH FIRST и т.д.), Вам нужно будет перетащить все записи, отсортировать их, прежде чем возвращать X записей. Я лгу — если это 1000 из 1 миллиарда, сетевой трафик значительно отличается. В любом случае, вы получаете представление о задействованных шагах и о том, как работает X.
Ответ №2:
Предполагая, что обе таблицы эквивалентны с точки зрения индекса, размера строк и других структур. Также предполагается, что вы используете эту простую инструкцию SELECT . Если у вас есть ORDER BY
предложение в ваших SQL-операторах, то, очевидно, что большая таблица будет работать медленнее. Я полагаю, вы спрашиваете не об этом.
Если X = Y, то, очевидно, они должны выполняться с одинаковой скоростью, поскольку механизм запросов будет просматривать записи в точно таком же порядке — в основном сканирование таблицы — для этого простого оператора SELECT . В плане запроса не будет никакой разницы.
Если Y > X только немного, то и скорость аналогичная.
Однако, если Y >> X (что означает, что у Y намного больше строк, чем у X), то версия LIMIT МОЖЕТ быть медленнее. Не из-за плана запроса — опять же, должно быть то же самое — а просто потому, что внутренняя структура компоновки данных может иметь еще несколько уровней. Например, если данные хранятся в виде листьев в дереве, может быть больше уровней дерева, поэтому для доступа к тому же количеству страниц может потребоваться немного больше времени.
Другими словами, 1000 строк могут храниться на 1 уровне дерева, скажем, на 10 страницах. 1000000 строк могут храниться на 3-4 уровнях дерева на 10000 страницах. Даже при использовании только 10 страниц из этих 10000 страниц механизму хранения все равно приходится проходить 3-4 уровня дерева, что может занять немного больше времени.
Теперь, если механизм хранения хранит страницы данных последовательно или, скажем, в виде связанного списка, то разницы в скорости выполнения не будет.
Ответ №3:
Это было бы примерно линейно, при условии, что вы не указываете поля, порядок и все записи. Но это не дает вам многого. Она разваливается, как только ваш запрос хочет сделать что-то полезное.
Это было бы немного интереснее, если бы вы намеревались сделать какой-нибудь полезный вывод и рассказать нам о том, как это можно было бы использовать для выбора дизайна в некотором контексте.
Спасибо за разъяснение.
По моему опыту, реальные приложения с реальными пользователями редко имеют интересные или полезные запросы, которые возвращают целые таблицы в миллион строк. Пользователи хотят знать о своей собственной активности или конкретной теме форума и т.д. Итак, если ваш случай не является необычным, к тому времени, когда вы действительно получите их критерии выбора, вы будете говорить о разумных размерах результата.
В любом случае пользователи не смогли бы сделать ничего полезного со многими строками, превышающими несколько сотен, их перенос занял бы много времени, и они не смогли бы прокручивать это каким-либо разумным способом.
MySQL имеет модификаторы LIMIT и OFFSET (# начальной записи), в первую очередь, для точной цели создания фрагментов списка для подкачки, как вы описываете.
Начинать думать о разработке схемы и очистке записей до тех пор, пока вы не используете эту и множество других стратегий, контрпродуктивно. В этом случае не решайте проблемы, которых у вас еще нет. Таблицы с несколькими миллионами строк не являются большими, практически говоря, до тех пор, пока они правильно проиндексированы.