我有以下數據:如何在XQuery中進行高效的外部或左連接?
<!-- subjects.xml -->
<Subjects>
<Subject>
<Id>1</Id>
<Name>Maths</Name>
</Subject>
<Subject>
<Id>2</Id>
<Name>Science</Name>
</Subject>
<Subject>
<Id>2</Id>
<Name>Advanced Science</Name>
</Subject>
<Subject>
<Id>3</Id>
<Name>History</Name>
</Subject>
</Subjects>
將被加入到:
<!-- courses.xml-->
<Courses>
<Course>
<SubjectId>1</SubjectId>
<Name>Algebra I</Name>
</Course>
<Course>
<SubjectId>1</SubjectId>
<Name>Algebra II</Name>
</Course>
<Course>
<SubjectId>1</SubjectId>
<Name>Percentages</Name>
</Course>
<Course>
<SubjectId>2</SubjectId>
<Name>Physics</Name>
</Course>
<Course>
<SubjectId>2</SubjectId>
<Name>Biology</Name>
</Course>
</Courses>
我希望做一個左連接上的第一個表到第二個表,以便得到以下輸出:
<Results>
<Result>
<Table1>
<Subject>
<Id>1</Id>
<Name>Maths</Name>
</Subject>
</Table1>
<Table2>
<Course>
<SubjectId>1</SubjectId>
<Name>Algebra I</Name>
</Course>
<Course>
<SubjectId>1</SubjectId>
<Name>Algebra II</Name>
</Course>
<Course>
<SubjectId>1</SubjectId>
<Name>Percentages</Name>
</Course>
</Table2>
</Result>
<Result>
<Table1>
<!-- Notice there are 2 subjects here, as they both have the same ID-->
<Subject>
<Id>2</Id>
<Name>Science</Name>
</Subject>
<Subject>
<Id>2</Id>
<Name>Advanced Science</Name>
</Subject>
</Table1>
<Table2>
<Course>
<SubjectId>2</SubjectId>
<Name>Physics</Name>
</Course>
<Course>
<SubjectId>2</SubjectId>
<Name>Biology</Name>
</Course>
</Table2>
</Result>
<Result>
<Table1>
<Subject>
<Id>3</Id>
<Name>History</Name>
</Subject>
</Table1>
<Table2>
<!-- Notice this section is empty -->
</Table2>
</Result>
</Results>
我有以下的代碼來做到這一點:
<Results>
{
(: For each element in courses, where it's 'SubjectId' exists in "subjects.xml":)
for $e2 in doc("courses.xml")/Courses/Course
let $foriegnId := $e2/SubjectId
group by $foriegnId
let $e1 := doc("subjects.xml")/Subjects/Subject[Id = $foriegnId]
where $e1
return
<Result>
<Table1>
{$e1}
</Table1>
<Table2>
{$e2}
</Table2>
</Result>
}
{
(: PART2 :)
(:Show the remaining elements in courses that have not yet been outputted:)
for $e1 in doc('subjects.xml')/Subjects/Subject
let $idVal := $e1/Id
group by $idVal
where not(doc('courses.xml')/Courses/Course/SubjectId = $idVal)
return
<Result>
<Table1>
{$e1}
</Table1>
<Table2/>
</Result>
}
</Results>
請注意代碼工作正常,並完成這項工作。但是,我發現在執行大量輸入代碼時(750個主題,每個主題有120個課程,100個主題沒有任何課程,100個主題沒有任何主題),劇本運行速度極慢!
怎樣才能讓我的腳本更快?有沒有更好的方法來做到這一點?時間複雜度是多少?
更新2
原來我已經嚴重誤判的問題。這個問題實際上與代碼的第2部分很少有關,而是代碼的第1部分。
我所做的是:
for $e2 in doc("courses.xml")/Courses/Course
let $foriegnId := $e2/SubjectId
let $e1 := doc("subjects.xml")/Subjects/Subject[Id = $foriegnId]
group by $foriegnId
的時候我應該做的是:
for $e2 in doc("courses.xml")/Courses/Course
let $foriegnId := $e2/SubjectId
group by $foriegnId
let $e1 := doc("subjects.xml")/Subjects/Subject[Id = $foriegnId]
這降低了代碼的時間從30,000ms左右4,000ms。
進一步的性能改進值得歡迎。
你可以給你的測量?你在使用撒克遜-HE還是撒克遜-EE? –
對於大型數據集的基準測試問題,僅提供小型提取(對於問題本身而言是很好的,但應該提供您針對自己進行基準測試的數據集)幾乎沒有幫助。另外,給出確切的軟件版本也很有幫助。 –
撒克遜9.7是evrsion我正在使用 –