SQL Server から long のリストを取得する最速の方法を探しています。
私が知る限り、以下のコードは通常実行できる最速のものであり、遅くするのは dr.Read() で発生するすべてのものと、各行に対する dr.GetInt64 の呼び出しです。
var ids = new long[count];
using (var dr = new SqlCommand(string.Format(@"SELECT TOP 10000 ID FROM Data", count),
conn).ExecuteReader(CommandBehavior.SequentialAccess))
{
while (dr.Read())
{
ids[i++] = dr.GetInt64(0);
}
}
クエリにかかる時間はごくわずかであるため、データ リーダーでの解析と型の検証に時間が費やされます。100,000 レコードの場合、配列内の 100,000 項目を反復するのにかかる 0.20 ミリ秒と比較して、約 25 ミリ秒かかります。
私は long のリストを求めているだけなので、それらを単一のバイト配列として取得できるかどうか疑問に思っています。私が求めているのは次のようなものです:
var bytes = (byte[]) new SqlCommand("(I don't know)", conn).ExecuteScalar();
Buffer.BlockCopy(bytes, 0, ids, 0, 10000);
これにより、解析時間が大幅に短縮されます。
このアプローチが可能かどうか教えてください。
アップデート:
少なくともこれらのアプローチは高速ではありません。
CLR 集計
.NET で記述されたカスタム集計関数を定義することができます。私は何もしない非常に単純なものを作ろうとしました(可能な限り高速にするために SqlUserDefinedAggregate(Format.Native) を使用)。これにより、クエリ時間が 60 ミリ秒に増加したため、これ以上速くなることはありません。
クエリは次のようになります。
SELECT dbo.ByteIt(ID) FROM (SELECT TOP 100000 ID FROM Data) T
varbinary の連結 (最大)
純粋な SQL を使用してバイト配列を構築することは可能です。それは非常に遅いです。
DECLARE @n varbinary(max)
SET @n = 0;
SELECT TOP 10000 @n = @n + cast(id as varbinary(8)) FROM Data;
SELECT @n;
努力する価値がおそらくない理由
私が考えることができる最速のネイティブ集計は COUNT です。
SELECT COUNT(ID) FROM (SELECT TOP 100000 ID FROM Data) T
これには 10 ミリ秒かかり、各値を考慮するメソッドの絶対下限でなければなりません。努力する価値のあるパフォーマンスの向上はないと思います。
悲しいことに、私の質問に対する答えは、「実行できますが、高速ではありません。25 ミリ秒で生きてください」だと思います。