Функция должна быть:
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;
}
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())
Стоимость этого будет заключаться в сканировании значений ключей плюс объединение стоимость, которая на большом столе при небольшом процентном выборе должна быть разумной.
В зависимости от ваших потребностей 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 .
Просто упорядочите таблицу по случайному числу и получите первые 5000 строк, используя TOP
.
SELECT TOP 5000 * FROM [Table] ORDER BY newid();
UPDATE
Только что попробовал и newid ( )
достаточно - нет необходимости во всех приведениях и всей математике.
В MySQL вы можете сделать это:
SELECT `PRIMARY_KEY`, rand() FROM table ORDER BY rand() LIMIT 5000;
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 следует использовать в крайнем случае, если у вас большой набор результатов.