-1

私たちの職場には、500万件のレコードを保持するクライアントテーブルを備えたデータベースがあります。クライアントが更新されるたびに、1億レコードを保持するclient_historyテーブルに別の行が追加されます。Clientテーブルのすべての列にインデックスが付けられます。クライアント履歴テーブルの主キー(ID)、外部キー(FK_Client_ID)、および作成タイムスタンプのみがインデックスに登録されます。

数十万のクライアントレコードを更新するように依頼されましたが、対応するクライアント履歴レコードが、特定の日付(たとえば、2012年9月19日)以降にクライアントレコードが更新されていないことを示している場合に限ります。

EXISTS句を使用するSQL更新クエリを作成しました。DBAから、EXISTS句を使用しないように言われました。これは、クエリの実行を遅くするテーブルスペーススキャンをトリガーするためです。これは、数十万のクライアントレコードを更新するときに明らかに問題になります-

UPDATE Client_History SET Surname = 'MisterX',
 Update_Timestamp = CURRENT_TIMESTAMP 
 WHERE (FK_Client_ID = 123 AND ID = 456)
 AND NOT EXISTS
 (SELECT * 
 FROM Client
 WHERE Client.Client_Id = Client_History.FK_Client_ID
 AND Client_History.Update_Timestamp > TIMESTAMP('2012-09-21-00:00:00')
 AND Client_History.Update_Timestamp < TIMESTAMP('4000-12-31-00:00:00')
 AND Client_History.Creation_Timestamp < NAME.Update_Timestamp);

誰かがより良い解決策を考えることができますか?

4

1 に答える 1

0

暗闇でのショット: すべての定数をメインクエリ (それらが属する場所) に引き上げてみてください

UPDATE Client_History ch
 SET Surname = 'MisterX'
     , Update_Timestamp = CURRENT_TIMESTAMP 
 WHERE ch.FK_Client_ID = 123
   AND ch.ID = 456
   AND ch.Update_Timestamp > TIMESTAMP('2012-09-21-00:00:00')
   AND ch.Update_Timestamp < TIMESTAMP('4000-12-31-00:00:00')
   AND ch.Creation_Timestamp < NAME.Update_Timestamp
   AND NOT EXISTS (
     SELECT * 
     FROM Client cl
     WHERE cl.Client_Id = ch.FK_Client_ID
     )
   ;

ところで:何NAMEですか?Oracle のdual?

于 2013-03-04T00:22:33.970 に答える