Sql

SQLServerテーブルからn個のランダムな行を選択します



Select N Random Rows From Sql Server Table



解決:

newid()による[yourtable]注文から上位10パーセント*を選択します

大きなテーブルに関する「純粋なゴミ箱」のコメントに応えて、パフォーマンスを向上させるためにこのようにすることができます。

select * from [yourtable] where [yourPk] in(select top 10パーセント[yourPk] from [yourtable] order by newid())

このコストは、値のキースキャンと結合コストの合計になります。これは、選択率が小さい大きなテーブルでは妥当なはずです。




あなたのニーズに応じて、TABLESAMPLEを使用すると、ほぼランダムでパフォーマンスが向上します。これは、MS SQL Server2005以降で使用できます。

TABLESAMPLEは、ランダムな行ではなくランダムなページからデータを返すため、deosは返さないデータを取得することさえしません。



私がテストした非常に大きなテーブルで

newid()による[テーブル名]の順序から上位1パーセント*を選択します

20分以上かかりました。

select * from [tablename] tablesample(1パーセント)

2分かかりました。



の小さなサンプルでもパフォーマンスが向上しますTABLESAMPLEはありませんが、変化する ()。

これは、newid()メソッドですが、適切なサンプリングが得られます。

MSDNページを参照してください。


newid()/ order byは機能しますが、すべての行のIDを生成してから並べ替える必要があるため、大きな結果セットの場合は非常にコストがかかります。

TABLESAMPLE()はパフォーマンスの観点からは優れていますが、結果がまとまります(ページ上のすべての行が返されます)。

真のランダムサンプルのパフォーマンスを向上させるための最良の方法は、行をランダムに除外することです。 SQL Server BooksOnlineの記事で次のコードサンプルを見つけました TABLESAMPLEを使用した結果セットの制限

個々の行のランダムなサンプルが本当に必要な場合は、TABLESAMPLEを使用する代わりに、クエリを変更して行をランダムに除外します。たとえば、次のクエリはNEWID関数を使用して、Sales.SalesOrderDetailテーブルの行の約1パーセントを返します。

SELECT * FROM Sales.SalesOrderDetail WHERE 0.01> = CAST(CHECKSUM(NEWID()、SalesOrderID)&0x7fffffff AS float)/ CAST(0x7fffffff AS int)

SalesOrderID列はCHECKSUM式に含まれているため、NEWID()は行ごとに1回評価され、行ごとにサンプリングを実行します。式CAST(CHECKSUM(NEWID()、SalesOrderID)&0x7fffffff AS float / CAST(0x7fffffff AS int)は、0から1までのランダムなfloat値に評価されます。

1,000,000行のテーブルに対して実行すると、次の結果が得られます。

SET STATISTICS TIME ON SET STATISTICS IO ON / *返されたnewid()行:10000論理読み取り:3359 CPU時間:3312ms経過時間= 3359 ms * / SELECT TOP 1 PERCENT Number FROM Numbers ORDER BY newid()/ * TABLESAMPLE行が返されました:9269(変動)論理読み取り:32 CPU時間:0ミリ秒経過時間:5ミリ秒* / SELECT Number FROM Numbers TABLESAMPLE(1 PERCENT)/ *返されたフィルター行:9994(変動)論理読み取り:3359 CPU時間:641ミリ秒経過時間:627ミリ秒* / 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()/ orderbyを最後の手段にする必要があります。