別のマテリアライズド・ビューに一致するレコードがあるレコードとして定義された、テーブルのサブセット(マテリアライズド・ビューとして)を作成しようとしています。
たとえば、user_id列とname列を持つUsersテーブルと、entry_id、user_id、activity、timestamp列を持つLogテーブルがあるとします。
まず、ログテーブルのマテリアライズドビューを作成し、タイムスタンプ>some_dateの行のみを選択します。ここで、ログテーブルのスナップショットで参照されているユーザーのマテリアルビューが必要です。私はそれを次のように作成することができます
select * from Users where user_id in (select user_id from Log_mview)
または私はすることができます
select distinct u.* from Users u inner join Log_mview l on u.user_id = l.user_id
(複数のログエントリを持つユーザーからの複数のヒットを回避するために、明確にする必要があります)。
前者はよりクリーンでエレガントに見えますが、はるかに時間がかかります。私は何かが足りないのですか?これを行うためのより良い方法はありますか?
編集:where exists
条件が。を使用する場合を除いて、句は大いに役立ちましたOR
。たとえば、上記のログテーブルにもuser_name列があり、ログエントリをUsersレコードに一致させる正しい方法は、列(ユーザーIDまたはユーザー名)のいずれかが一致する場合です。私はそれを見つけています
select distinct u.* from Users u
inner join Log_mview l
on u.user_id = l.user_id or u.name = l.user_name
よりもはるかに高速です
select * from Users u where exists
(select id from Log_mview l
where l.user_id = u.user_id or l.user_name = u.name)
何か助けはありますか?
(説明計画に関しては...レムはそれを消毒することに取り組んでいます、あるいはそれらはむしろ...私はそれらをしばらく投稿します。)
編集:計画の説明:内部結合を使用したクエリの場合:
計画ハッシュ値:436698422 -------------------------------------------------- -------------------------------------------------- ----------- | Id | 操作| 名前| 行| バイト|TempSpc| コスト(%CPU)| 時間| -------------------------------------------------- -------------------------------------------------- ----------- | 0 | ステートメントの選択| | 4539K | 606M | | 637K(3)| 02:07:25 | | 1 | ハッシュユニーク| | 4539K | 606M | 3201M | 637K(3)| 02:07:25 | | 2 | 連結| | | | | | | | * 3 | ハッシュ結合| | 4206K | 561M | 33M | 181K(4)| 00:36:14 | | 4 | ROWIDへのビットマップ変換| | 926K | 22M | | 2279(1)| 00:00:28 | | 5 | BITMAP INDEX FAST FULL SCAN | I_M_LOG_MVIEW_4 | | | | | | | * 6 | テーブルアクセスフル| ユーザー| 15M | 1630M | | 86638(6)| 00:17:20 | | * 7 | ハッシュ結合| | 7646K | 1020M | 33M | 231K(4)| 00:46:13 | | 8 | ROWIDへのビットマップ変換| | 926K | 22M | | 2279(1)| 00:00:28 | | 9 | BITMAP INDEX FAST FULL SCAN | I_M_LOG_MVIEW_4 | | | | | | | 10 | テーブルアクセスフル| ユーザー| 23M | 2515M | | 87546(7)| 00:17:31 | -------------------------------------------------- -------------------------------------------------- ----------- 述語情報(操作IDで識別): -------------------------------------------------- - 3-access("U"。"NAME" ="L"。"USER_NAME") 6-filter("U"。"NAME" IS NOT NULL) 7-access("U"。"USER_ID" = TO_NUMBER("L"。"USER_ID")) filter(LNNVL("U"。"NAME" ="L"。"USER_NAME")またはLNNVL("U"。"NAME" IS NOT NULL)) ノート ----- -このステートメントに使用される動的サンプリング
使用しているものの場合where exists
:
計画ハッシュ値:2786958565 -------------------------------------------------- -------------------------------------------------- - | Id | 操作| 名前| 行| バイト| コスト(%CPU)| 時間| -------------------------------------------------- -------------------------------------------------- - | 0 | ステートメントの選択| | 1 | 114 | 21M(1)| 70:12:13 | | * 1 | フィルター| | | | | | | 2 | テーブルアクセスフル| ユーザー| 23M | 2515M | 87681(7)| 00:17:33 | | 3 | ROWIDへのビットマップ変換| | 7062 | 179K | 1(0)| 00:00:01 | | * 4 | BITMAP INDEX FAST FULL SCAN | I_M_LOG_MVIEW_4 | | | | | -------------------------------------------------- -------------------------------------------------- - 述語情報(操作IDで識別): -------------------------------------------------- - 1-filter(EXISTS(SELECT / * + * / 0FROM"MYSCHEMA"。"LOG_MVIEW" "LOG_MVIEW" WHERE( "USER_NAME" =:B1 OR TO_NUMBER( "USER_ID")=:B2)AND ("USER_NAME" =:B3 OR TO_NUMBER( "USER_ID")=:B4)AND( "USER_NAME" =:B5 OR TO_NUMBER( "USER_ID")=:B6))) 4-filter( "USER_NAME" =:B1 OR TO_NUMBER( "USER_ID")=:B2) ノート ----- -このステートメントに使用される動的サンプリング
無実を保護するためにDBオブジェクト名が変更されました。:p