Выберите n случайные строки из таблицы SQL Server

Функция должна быть:

void pushINT(int **arr,int *size,int data) {
    int *tmp=realloc(*arr,(*size+1)*sizeof(int));
    if (tmp==NULL) exit(100);
    *arr= tmp;
    tmp[*size]=data;
    (*size)=*size+1;
}

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


Или, как предлагает Джонатан Леффлер:

int *pushINT(int *arr,int *size,int data) {
    int *tmp=realloc(arr,(*size+1)*sizeof(int));
    if (tmp==NULL) exit(100);
    tmp[*size]=data;
    (*size)=*size+1;
    return tmp;
}
295
задан Peter O. 29 September 2013 в 17:06
поделиться

5 ответов

select top 10 percent * from [yourtable] order by newid()

В ответ на комментарий «чистый мусор», касающийся больших таблиц: вы можете сделать это так, чтобы повысить производительность.

select  * from [yourtable] where [yourPk] in 
(select top 10 percent [yourPk] from [yourtable] order by newid())

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

370
ответ дан 23 November 2019 в 01:34
поделиться

В зависимости от ваших потребностей TABLESAMPLE даст вам почти такую ​​же случайную и лучшую производительность. это доступно на сервере MS SQL 2005 и новее.

TABLESAMPLE будет возвращать данные со случайных страниц вместо случайных строк, и поэтому deos даже не извлекает данные, которые не вернет.

На очень большой таблице, которую я тестировал

select top 1 percent * from [tablename] order by newid()

, потребовалось более 20 минут.

select * from [tablename] tablesample(1 percent)

занял 2 минуты.

Производительность также улучшится на небольших выборках в TABLESAMPLE , тогда как в newid () этого не произойдет.

Имейте в виду, что это не так. такой же случайный, как метод newid () , но даст вам приличную выборку.

См. страницу MSDN .

78
ответ дан 23 November 2019 в 01:34
поделиться

Просто упорядочите таблицу по случайному числу и получите первые 5000 строк, используя TOP .

SELECT TOP 5000 * FROM [Table] ORDER BY newid();

UPDATE

Только что попробовал и newid ( ) достаточно - нет необходимости во всех приведениях и всей математике.

8
ответ дан 23 November 2019 в 01:34
поделиться

В MySQL вы можете сделать это:

SELECT `PRIMARY_KEY`, rand() FROM table ORDER BY rand() LIMIT 5000;
3
ответ дан 23 November 2019 в 01:34
поделиться

newid () / order by будет работать, но будет очень дорого для больших наборов результатов, потому что он должен генерировать идентификатор для каждой строки, а затем сортировать их.

TABLESAMPLE () это хорошо с точки зрения производительности, но вы получите сгруппированные результаты (будут возвращены все строки на странице).

Для лучшей производительности истинной случайной выборки лучше всего отфильтровать строки случайным образом. Я нашел следующий образец кода в статье электронной документации по SQL Server Ограничение наборов результатов с помощью TABLESAMPLE :

Если вам действительно нужна случайная выборка отдельные строки, измените свой запрос на отфильтровывать строки случайным образом вместо используя TABLESAMPLE. Например, в следующем запросе используется NEWID функция для возврата примерно одного процентов строк Таблица Sales.SalesOrderDetail:

 ВЫБРАТЬ * ИЗ Sales.SalesOrderDetail
WHERE 0.01> = CAST (КОНТРОЛЬНАЯ СУММА (NEWID (), SalesOrderID) & 0x7fffffff AS с плавающей запятой)
 / CAST (0x7fffffff как целое)

Столбец SalesOrderID включен в выражение CHECKSUM так, чтобы NEWID () вычисляет один раз для каждой строки добиться выборки для каждой строки. Выражение CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS с плавающей запятой / CAST (0x7fffffff AS int) оценивается как случайное значение с плавающей запятой от 0 до 1.

При запуске с таблицей с 1 000 000 строк, вот мои результаты:

SET STATISTICS TIME ON
SET STATISTICS IO ON

/* newid()
   rows returned: 10000
   logical reads: 3359
   CPU time: 3312 ms
   elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()

/* TABLESAMPLE
   rows returned: 9269 (varies)
   logical reads: 32
   CPU time: 0 ms
   elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)

/* Filter
   rows returned: 9994 (varies)
   logical reads: 3359
   CPU time: 641 ms
   elapsed time: 627 ms
*/    
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float) 
              / CAST (0x7fffffff AS int)

SET STATISTICS IO OFF
SET STATISTICS TIME OFF

Если вам удастся использовать TABLESAMPLE, это даст вам лучшую производительность. В противном случае используйте метод newid () / filter. newid () / order by следует использовать в крайнем случае, если у вас большой набор результатов.

37
ответ дан 23 November 2019 в 01:34
поделиться
Другие вопросы по тегам:

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