Подтвердить что ты не робот

"order by newid()" - как это работает?

Я знаю, что если я запустил этот запрос

select top 100 * from mytable order by newid()

он получит 100 случайных записей из моей таблицы.

Однако я немного смущен относительно того, как это работает, поскольку я не вижу newid() в списке select. Может кто-нибудь объяснить? Что-то особенное в newid() здесь?

4b9b3361

Ответ 1

Я знаю, что делает NewID(), я просто пытаясь понять, как это поможет в случайном выборе. Это оно (1) оператор select выберет ВСЕ из таблицы, (2) для каждого выбранная строка, наложение на uniqueidentifier, сгенерированный NewID(), (3) сортировать строки этим uniqueidentifier и (4) выбрать топ 100 из отсортированного списка?

Да. это почти точно верно (за исключением того, что не обязательно сортировать все строки). Вы можете проверить это, посмотрев фактический план выполнения.

SELECT TOP 100 * 
FROM master..spt_values 
ORDER BY NEWID()

Скалярный оператор вычисления добавляет столбец NEWID() для каждой строки (2506 в таблице в моем примере запроса), тогда строки в таблице сортируются по этому столбцу с выбранными 100 точками.

SQL Server действительно не нужно сортировать весь набор с позиций 100 вниз, поэтому он использует оператор сортировки TOP N, который пытается выполнить всю операцию сортировки в памяти (для небольших значений N)

План

Ответ 2

В целом он работает следующим образом:

  • Все строки из mytable "зациклированы"
  • NEWID() выполняется для каждой строки
  • Строки сортируются в соответствии со случайным числом из NEWID()
  • 100 первых строк выбраны

Ответ 3

Ключ здесь - функция NEWID, которая генерирует глобально уникальный идентификатор (GUID) в памяти для каждой строки. По определению GUID является уникальным и довольно случайным; поэтому, когда вы сортируете по этому GUID с предложением ORDER BY, вы получаете случайное упорядочение строк в таблице. Взяв верхние 10 процентов (или любой процент, который вы хотите), вы получите случайную выборку строк в таблице.

Предлагается запрос NEWID; это просто и отлично работает для небольших столов. Однако запрос NEWID имеет большой недостаток, когда вы используете его для больших таблиц. Предложение ORDER BY заставляет все строки в таблице копироваться в базу данных tempdb, где они сортируются. Это вызывает две проблемы: Операция сортировки обычно связана с высокой стоимостью. Сортировка может использовать много дискового ввода-вывода и может работать в течение длительного времени. В худшем случае tempdb может закончиться. В лучшем случае tempdb может занимать большое количество дискового пространства, которое никогда не будет восстановлено без команды ручной усадки. То, что вам нужно, - это способ случайного выбора строк, которые не будут использовать tempdb, и не будут становиться намного медленнее, поскольку таблица становится больше. Вот новая идея о том, как это сделать:

SELECT * FROM master..spt_values
  WHERE (ABS(CAST(
  (BINARY_CHECKSUM(*) *
  RAND()) as int)) % 100) < 10

Основная идея этого запроса заключается в том, что мы хотим создать случайное число от 0 до 99 для каждой строки в таблице, а затем выбрать все те строки, случайное число которых меньше значения указанного процента. В этом примере мы хотим, чтобы примерно 10 процентов строк были выбраны случайным образом; поэтому мы выбираем все строки, случайное число которых меньше 10.

Ответ 4

as MSDN говорит:

NewID() Создает уникальное значение типа UniqueIdentifier.

и ваша таблица будет отсортирована по этим случайным значениям.

Ответ 5

использовать select top 100 randid = newid(), * from mytable order by randid вы будете уточнены тогда..