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 OFFTABLESAMPLEの使用をやめることができれば、最高のパフォーマンスが得られます。それ以外の場合は、newid()/ filterメソッドを使用します。結果セットが大きい場合は、newid()/ orderbyを最後の手段にする必要があります。