Строки 100k, Возвращенные в произвольном порядке, без SQL, испытывают таймаут

Хорошо,

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

ORDER BY newid()

Это хорошо для <5k строки. Но когда мы добираемся> 10-20k строки, мы получаем время SQL outs, запланированное Выполнение говорит мне, что 76% моей стоимости запроса прибывают из этой строки. и удаление этой строки увеличивает скорость порядком величины, когда у нас есть большая сумма строк.

У наших пользователей есть требование выполнения до 100k строк в такое время.

Предоставлять Вам всем немного больше подробной информации.

У нас есть таблица с 2,6 миллионами 4 буквенно-цифровых кода цифры. Мы используем случайный набор их для получения записи в место проведения. Например, если у нас будет событие с 5 000 способности, то случайный набор 5000 из них будет оттянут из таблицы, затем выпущенной каждому клиенту как штрихкод, затем приложение сканирования штрихкода у двери с имеет тот же список 5000. Причина использования 4 альфа-цифровых кодов цифры (и не глупо длинное количество как GUID) состоит в том, что ему легкий для людей записать число (или SMS это другу) и просто принести число и ввели его вручную, таким образом, мы не хотим большого количества символов. Клиенты любят последний бит btw.

Есть ли лучший путь, чем ORDER BY newid(), или есть ли более быстрый способ получить 100k случайные строки от таблицы с 2,6 миллиметрами?

О, и мы используем MS SQL 2005.

Спасибо,

Jo

5
задан Earlz 24 February 2010 в 00:00
поделиться

6 ответов

Существует статья MSDN под названием "Выбор строк случайным образом из большой таблицы", в которой говорится именно об этой проблеме и показано решение (без сортировки, а с использованием предложения WHERE на сгенерированном столбце для фильтрации строк).

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

7
ответ дан 13 December 2019 в 19:26
поделиться

Интересно, какова производительность, если вы замените

ORDER BY newid()

на

ORDER BY CHECKSUM(newid())
0
ответ дан 13 December 2019 в 19:26
поделиться

Если вы хотите сгенерировать случайные 4-значные коды, почему бы просто не сгенерировать их вместо того, чтобы пытаться извлечь их из базы данных?

Сгенерировать 100 тысяч уникальных чисел от 0 до 1 679 616 (что является количество уникальных четырехзначных буквенно-цифровых кодов без учета регистра (2,6 миллиона строк должны иметь несколько дубликатов) и преобразовать их в ваши четырехзначные коды.

3
ответ дан 13 December 2019 в 19:26
поделиться

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

0
ответ дан 13 December 2019 в 19:26
поделиться

Вам не нужно сортировать.

 DECLARE @RandomNumber int
 DECLARE @Threshold float
 SELECT @RandomNumber = COUNT(*) FROM customers
 SELECT @Threshold = 50000 / @RandomNumber

 SELECT TOP 50000 * FROM customers WHERE rand() > @Threshold ORDER BY newid()
1
ответ дан 13 December 2019 в 19:26
поделиться

Пробовали ли вы использовать % (modulo) для данного столбца int? Не уверен, какова структура вашей таблицы, но вы могли бы сделать что-то вроде этого:

select top 50000 * из вашей_таблицы where CAST((CAST(ASCII(SUBSTRING(venuecode,1,1)) as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,2,1)) as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,3,1))as varchar(3))+ CAST(ASCII(SUBSTRING(venuecode,4,1))as varchar(3))) as bigint) % 500000 между 0 и 50000

Приведенный выше код возьмет все ваши альфа-числовые значения и преобразует их в целое число, а затем разделит всю таблицу на 500000 ведер, из которых вы возьмете 50000 лучших, которые находятся между 0 и 50000. Вы можете играть с числом после % (500 000) и с числом между ними. Это должно рандомизировать его для вас. Не уверен, что условие where повлияет на производительность, но попробовать стоит. Кроме того, без order by нет гарантии порядка (если у вас несколько процессоров и потоков).

0
ответ дан 13 December 2019 в 19:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: