さまざまな類似の質問がありましたが、あまりにも特定のDBを参照するか、未ソートデータを想定していました。次の使用されていないインデックス、汎用SQLでの順序付き挿入
可能であれば、SQLは移植可能でなければなりません。問題のインデックス列は、タイムスタンプを含むクラスタ化されたPKです。
タイムスタンプは、以前に挿入された値より大きい時間の99%です。ただし、まれにしか小さくても、既存の値と衝突することもあります。
私は現在、新しい値を挿入するには、このコードを使用しています:行が使用されていない、まだ
IF NOT EXISTS (select * from Foo where Timestamp = @ts) BEGIN
INSERT INTO Foo ([Timestamp]) VALUES (@ts);
END
ELSE BEGIN
INSERT INTO Foo ([Timestamp]) VALUES (
(SELECT Max (t1.Timestamp) - 1
FROM Foo t1
WHERE Timestamp < @ts
AND NOT EXISTS (select * from Foo t2 where t2.Timestamp = t1.Timestamp - 1))
);
END;
場合、単に挿入します。そうでない場合は、EXISTS
小切手を使用して、最も小さな空き行を見つけます。
私はデータベースに関しては初心者ですので、より良い方法があるかどうかはわかりません。私は、コードをよりシンプルに、より速く(1秒あたり約100-1000回の挿入)、または別のアプローチを全く使用するためのアイデアはいつでも開いています。
あなたのコメントをお寄せいただきありがとうございます。
私の場合の性質について説明する:タイムスタンプはデータをソートするために使用された唯一の値ですが、マイナーな不一致は無視できます。 FKの関係はありません。
しかし、私は自分のアプローチに欠陥があり、最初に提示されたアイデアを使用する理由を上回ることに同意します。私が正しく理解していれば、デザインを修正する簡単な方法は、定期的に自動インクリメントされたPK列を既知の(および名前を変更した)タイムスタンプ列と組み合わせてクラスタ化することです。
パフォーマンスPOVからは、これが最初のアプローチよりも悪化する可能性はありません。また、コードを多く簡略化します。
私はあなたがseriosly間違った道にいると思います。まず第一に、あなたのタイムスタンプがどう違うのでしょうか?同時に2つのことが起こる場合、タイムスタンプは同じでなければなりません。第二に、PK(クラスタ化されているかどうか)に現実の価値を使用することは一般的に推奨されていません。オートインクリメントIDを使用し、タイムスタンプをそのまま保存してください。 (タイムスタンプフィールドにインデックスを使用することを検討することがあります) –
タイムスタンプがデータの適切なプライマリキーであることを確認してください。時にはそれが重複することができれば、おそらくそうではありません。そうであれば、なぜその質問に答えるのに役立つかもしれないのか。または、これは基本的にアイデンティティーの問題です(つまり、タイムスタンプの違いを使って2つのレコードの違いを伝えることができます - 重複していると思われる場合はほとんど間違っていると思います)か、効率的なデータ取得の問題ですか?後者の場合、別のプライマリキーを選択してインデックスを片面更新の方に変更すると、よりうまくいく可能性があります。 – dataduck