質問
最善の方法でテーブルにスワップしたい。
IpToCountryテーブルがあり、インポートする外部CSVファイルに従って毎週新しいテーブルを作成します。
切り替えを行うために見つけた最速の方法は、次のことです。
sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go
これに関する問題は、テーブルがまだアクセスされる可能性があることです。
SQLでこの問題に対処するにはどうすればよいですか?
sp_getapplockとsp_releaseapplockの使用を検討しましたが、テーブル関数からの読み取りを可能な限り高速に保ちたいと考えています。
解決
既存のテーブルに更新/挿入できないと仮定して、表示?
たとえば、最初に IpToCountry20090303 というテーブルにデータを保存すると、ビューは次のようになります。
CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303
新しいデータが入ったら、 IpToCountry20090310 テーブルを作成してデータを追加できます。テーブルにデータが入力されたら、ビューを更新します。
ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310
スイッチは完全にアトミックであり、明示的なロックやトランザクションは必要ありません。ビューが更新されたら、古いテーブルを単にドロップするか、必要に応じて保持します。
他のヒント
達成しようとしていることを実装する別の方法は、SQL ServerのEnterprise Editionで利用可能な手法であるテーブルパーティションの使用です。
テーブル名は同じままでかまいません。テーブルのインポートが完了したら、単に古いデータを含むパーティションを切り替えて、新しいパーティションに切り替えるだけです。
次のホワイトペーパーには、開始に必要なすべての情報が含まれています。
http://msdn.microsoft.com/en-us/library /ms345146.aspx
乾杯、ジョン
パーティション機能を大規模に動作させるのに問題がありました。 CREATEおよびDROP PARTITIONはブロック操作であり、ブロックを制御する方法はほとんどありません。ロックを取得できない場合、重大度レベル16で失敗し、接続を終了します。再確立せずにトラップして再試行することはできません。接続。しかし、それはあなたのためにうまくいくかもしれません。また、MSS Enterprise Editionが必要です。SEは使用できません。小規模またはコスト重視のショップにとっては多すぎるかもしれません。
また、ビューredefがsysテーブルおよびオブジェクトで大規模(=トランザクションボリューム+常時挿入されたデータの膨大なボリューム)でブロックするため、これらの操作はインデックスの再作成やDTCC-場合によっては、特にSSMSのユーザーがオブジェクトエクスプローラーでビューを閲覧しようとしている場合(誰かがそれらの人にREADPASTについて伝える必要があります)。繰り返しますが、走行距離は異なる場合があります。
対照的に、sp_renameは大規模にうまく機能します。ロックとスコープを制御できます。スワップの前にブロッキングの問題を解決するには、以下に示すように試してください。額面では、これは大容量でも同じ規模の問題を抱えているように思われますが、実際には見ていません。だから、私のために働く...しかし、再び、すべての人のニーズと経験は異なっています。
DECLARE @dummylock bit
BEGIN TRANSACTION
BEGIN TRY
-- necessary to obtain exclusive lock on the table prior to swapping
SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX))
-- may or may not be necessary in your case
SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX))
exec sp_rename 'A', 'TEMP'
exec sp_rename 'B', 'A'
exec sp_rename 'TEMP', 'B'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- other error handling here if needed
ROLLBACK TRANSACTION
END CATCH
IpToCountryOldはどうなりますか?捨てますか?その場合は、IpToCountryを切り捨てて新しいデータをインポートしてください。
データを保持する必要がある場合は、ロード日付をテーブルに保存し、「現在」を保存してくださいWHERE句で使用する日付をどこかにロードしますか?次に、データが正常にロードされたときに現在の日付を切り替えます。
使用しているDBがわからないので、これがどの程度使用されているかわかりませんが、テーブルを参照するストアドプロシージャはありますか?一部のプラットフォームでは、SPは名前の変更で変更されないテーブルへの内部参照を使用してコンパイルされるため、SPが再コンパイルしないと新しいデータを取得しないリスクがあることに注意してください。ビューおよび保存された解析済みクエリにも同じことが言えます。
営業時間外に1つのテーブルへのインポートを実行できませんか?
または、データを更新するだけではありません。つまり、既存のレコードを更新し、ループしてデータをインポートするときに、レコードごとに新しいレコードを追加します。これにより、テーブルをライブに保ち、テーブル全体を追加および削除することによる全体的な影響を軽減できます。
インポートするデータの構造、テーブルのデザイン、形式、PKなどは何ですか?それにより、より良い回答を提供できる場合があります。
ジャストステージングテーブルで同様の問題が発生し、適切なロックによるスケーリングの問題が発生しました。
テーブルが参照されるすべての場所で、テーブル名を要求するストアドプロシージャを呼び出すことができます。
ストアドプロシージャは、オプションで新しいテーブルを作成するか、指定されたパラメーターに応じて古いテーブルを返します。