考虑这个简化的Adobe Premiere项目文件:
<Project>
<Sequences>
<UID.1>a</UID.1>
<UID.2>b</UID.2>
<UID.3>c</UID.3>
</Sequences>
</Project>
<Sequence ObjectUID="a"> ... </Sequence>
<Sequence ObjectUID="b"> ... </Sequence>
<Sequence ObjectUID="c"> ... </Sequence>
<Sequence ObjectUID="x"> ... </Sequence>
目标是找到 Project / Sequences / UID.N
引用的所有Sequence元素我构建了这个Xpath查询:
/Sequence[@ObjectUID=
/Project/Nodes/*[starts-with(local-name(),"UID.")]
]
这个问题是,对于一个非常大的XML文件(100 MB),即使其中只有20个Sequence元素,以及同一级别的10000个其他兄弟,搜索需要很多秒。
如果我只收集内部查询的结果,即来自
/Project/Nodes/*[starts-with(local-name(),"UID.")]
然后遍历20个UID,通过/PremiereData/Sequence[@ObjectUID='a']
的ObjectUID获取每个序列,依此类推,它非常快。
这告诉我,Xpath处理器没有像我期望的那样首先评估(并且不变)内部表达式,然后选择外部expr的元素,而是首先获取所有序列,然后重新评估每个人的内在谓词,这就是让它变得如此缓慢的原因。
我是对的吗?我可以更改查询以便不会发生这种情况,或者可以添加提示以告诉表达式评估者谓词是不变的吗?
答案 0 :(得分:2)
大多数XPath处理器不进行任何智能连接优化,它们只使用嵌套循环。 Saxon-EE是我所知道的唯一一个以你建议的方式优化连接的处理器。
如果您使用的是XSLT,那么使用xsl:key是常用的解决方法,但在纯XPath中,没有简单的答案 - 特别是如果它是XPath 1.0。
答案 1 :(得分:0)
处理器可能正在重新评估谓词中的表达式,如果您首先选择UID元素值并绑定到变量,然后在{的谓词过滤器中使用该变量,您会看到性能提升{1}}元素。
Sequence