つまり、なぜこれを行うのですか:
select *
from tableA
/* Bunch of inner joins */
where
/* Bunch of clauses */
and (
exists (
select *
from tableB, tableC, tableD
where (tableB.fieldNameA = 'foo') and
/* More clauses */
) or
exists (
select *
from tableB, tableC, tableD
where (tableB.fieldNameA = 'bar') and
/* More clauses */
)
)
これより約 500 倍高速に実行できますか?
select *
from tableA
/* Bunch of inner joins */
where
/* Bunch of clauses */
and exists (
select *
from tableB, tableC, tableD
where (tableB.fieldNameA = 'foo' or tableB.fieldNameA = 'bar') and
/* More clauses */
)
私はコードを繰り返さないという考えが好きなので、2 番目のバージョンに統合したいと考えました。どちらも同じ結果セットを生成しますが、最初の実行は非常に高速で、使用できません。考え?
私はクエリプランを調べてきましたが、実際にはその底がわかりませんでした. 私が気づいたことの 1 つは、因数分解された例では、クラスター化インデックス シーク[tree].[PK__tree__09746778]
の実際の行数が 93,000 近くあることです。もう 1 つの例では、これほど多くの行数はありません。これがテキスト出力です。これがどれほど役立つかはわかりません。
最初の例 (デファクタリング) は以下を生成します:
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([initialCategory].[inode]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[tree].[child]))
| |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[course].[inode])=([OPUSDev2].[dbo].[tree].[parent]), RESIDUAL:([OPUSDev2].[dbo].[course].[inode]=[OPUSDev2].[dbo].[tree].[parent]))
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[section].[inode], [Expr1037]) WITH UNORDERED PREFETCH)
| | | |--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[course_term].[inode], [Expr1036]) WITH UNORDERED PREFETCH)
| | | | |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[course].[course_number])=([OPUSDev2].[dbo].[course_term].[course_number]), RESIDUAL:([OPUSDev2].[dbo].[course_term].[course_number]=[OPUSDev2].[dbo].[course].[course_number]))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[course].[PK__course__31B762FC]), WHERE:(CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[course].[show_on_web],0)=(1) AND CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[course].[show_on_nav],0)=(1)))
| | | | | |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[term].[term_id])=([OPUSDev2].[dbo].[course_term].[term_id]))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[term].[PK__term__0697FACD]), WHERE:(CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[term].[active_on_web],0)=(1)))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[course_term].[course_term_pk]))
| | | | |--Index Seek(OBJECT:([OPUSDev2].[dbo].[section].[section_idx2]), SEEK:([OPUSDev2].[dbo].[section].[course_term_inode]=[OPUSDev2].[dbo].[course_term].[inode]) ORDERED FORWARD)
| | | |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[section].[PK__section__7B264821]), SEEK:([OPUSDev2].[dbo].[section].[inode]=[OPUSDev2].[dbo].[section].[inode]), WHERE:([OPUSDev2].[dbo].[section].[status]='Active') LOOKUP ORDERED FORWARD)
| | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[tree].[PK__tree__09746778]))
| |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[PK__category__2739D489] AS [initialCategory]), SEEK:([initialCategory].[inode]=[OPUSDev2].[dbo].[tree].[child]), WHERE:([OPUSDev2].[dbo].[category].[active] as [initialCategory].[active]=(1)) ORDERED FORWARD)
|--Concatenation
|--Nested Loops(Inner Join)
| |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[PK__category__2739D489] AS [childCategory]), SEEK:([childCategory].[inode]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode]) ORDERED FORWARD)
| |--Nested Loops(Inner Join, OUTER REFERENCES:([parentCategory].[inode]))
| |--Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[idx_category_2] AS [parentCategory]), SEEK:([parentCategory].[category_key]='noncredit_subjects') ORDERED FORWARD)
| |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[tree].[PK__tree__09746778]), SEEK:([OPUSDev2].[dbo].[tree].[child]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode] AND [OPUSDev2].[dbo].[tree].[parent]=[OPUSDev2].[dbo].[category].[inode] as [parentCategory].[inode]) ORDERED FORWARD)
|--Nested Loops(Inner Join)
|--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[PK__category__2739D489] AS [childCategory]), SEEK:([childCategory].[inode]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode]) ORDERED FORWARD)
|--Nested Loops(Inner Join, OUTER REFERENCES:([parentCategory].[inode]))
|--Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[idx_category_2] AS [parentCategory]), SEEK:([parentCategory].[category_key]='credit_subjects') ORDERED FORWARD)
|--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[tree].[PK__tree__09746778]), SEEK:([OPUSDev2].[dbo].[tree].[child]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode] AND [OPUSDev2].[dbo].[tree].[parent]=[OPUSDev2].[dbo].[category].[inode] as [parentCategory].[inode]) ORDERED FORWARD)
2 番目の例 (因数分解) は次のようになります。
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([initialCategory].[inode]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[tree].[child]))
| |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[course].[inode])=([OPUSDev2].[dbo].[tree].[parent]), RESIDUAL:([OPUSDev2].[dbo].[course].[inode]=[OPUSDev2].[dbo].[tree].[parent]))
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[section].[inode], [Expr1029]) WITH UNORDERED PREFETCH)
| | | |--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[course_term].[inode], [Expr1028]) WITH UNORDERED PREFETCH)
| | | | |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[course].[course_number])=([OPUSDev2].[dbo].[course_term].[course_number]), RESIDUAL:([OPUSDev2].[dbo].[course_term].[course_number]=[OPUSDev2].[dbo].[course].[course_number]))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[course].[PK__course__31B762FC]), WHERE:(CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[course].[show_on_web],0)=(1) AND CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[course].[show_on_nav],0)=(1)))
| | | | | |--Hash Match(Inner Join, HASH:([OPUSDev2].[dbo].[term].[term_id])=([OPUSDev2].[dbo].[course_term].[term_id]))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[term].[PK__term__0697FACD]), WHERE:(CONVERT_IMPLICIT(tinyint,[OPUSDev2].[dbo].[term].[active_on_web],0)=(1)))
| | | | | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[course_term].[course_term_pk]))
| | | | |--Index Seek(OBJECT:([OPUSDev2].[dbo].[section].[section_idx2]), SEEK:([OPUSDev2].[dbo].[section].[course_term_inode]=[OPUSDev2].[dbo].[course_term].[inode]) ORDERED FORWARD)
| | | |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[section].[PK__section__7B264821]), SEEK:([OPUSDev2].[dbo].[section].[inode]=[OPUSDev2].[dbo].[section].[inode]), WHERE:([OPUSDev2].[dbo].[section].[status]='Active') LOOKUP ORDERED FORWARD)
| | |--Clustered Index Scan(OBJECT:([OPUSDev2].[dbo].[tree].[PK__tree__09746778]))
| |--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[PK__category__2739D489] AS [initialCategory]), SEEK:([initialCategory].[inode]=[OPUSDev2].[dbo].[tree].[child]), WHERE:([OPUSDev2].[dbo].[category].[active] as [initialCategory].[active]=(1)) ORDERED FORWARD)
|--Nested Loops(Inner Join)
|--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[PK__category__2739D489] AS [childCategory]), SEEK:([childCategory].[inode]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode]) ORDERED FORWARD)
|--Nested Loops(Inner Join, OUTER REFERENCES:([OPUSDev2].[dbo].[tree].[parent]))
|--Clustered Index Seek(OBJECT:([OPUSDev2].[dbo].[tree].[PK__tree__09746778]), SEEK:([OPUSDev2].[dbo].[tree].[child]=[OPUSDev2].[dbo].[category].[inode] as [initialCategory].[inode]) ORDERED FORWARD)
|--Index Seek(OBJECT:([OPUSDev2].[dbo].[category].[idx_category_2] AS [parentCategory]), SEEK:([parentCategory].[category_key]='credit_subjects' AND [parentCategory].[inode]=[OPUSDev2].[dbo].[tree].[parent] OR [parentCategory].[category_key]='noncredit_subjects' AND [parentCategory].[inode]=[OPUSDev2].[dbo].[tree].[parent]) ORDERED FORWARD)