我有用于保存XML文档的数据库。 数据库看起来像这样:
所以我可以将任何XML文件保存到我的通用数据库中。
然后我将XPATH查询翻译成SQL查询,用于选择元素。
1) // EMPTY [./ PERIOD ]
SELECT e2.docId
, e2.startPos
, e2.endPos
, p2.NodeName
, p2.levelEl
, p2.pathID
From Path p2
, Element e2
, Path p3
, Element e3
WHERE e2.docID = p2.docID
AND e2.pathID = p2.pathID
AND p2.NodeName = 'EMPTY'
AND p2.levelEl >= 1
AND e3.docID = p3.docID
AND e3.pathID = p3.pathID
AND p3.NodeName = '_PERIOD_'
AND e2.startPos < e3.startPos
AND e2.endPos > e3.endPos
AND e2.docId = e3.docId
AND p2.levelEl = p3.levelEl - 1
AND e2.docId
= 3147524262 GROUP BY e2.docId
, e2.startPos
, e2.endPos
, p2.NodeName
, p2.levelEl
, p2.pathID
ORDER BY startPos;
2) // EMPTY [./ PERIOD ] / S / NP
SELECT e5.docId
, e5.startPos
, e5.endPos
, p5.NodeName
, p5.levelEl
, p5.pathID
From Path p2
, Element e2
, Path p3
, Element e3
, Path p4
, Element e4
, Path p5
, Element e5
WHERE e2.docID = p2.docID
AND e2.pathID = p2.pathID
AND p2.NodeName = 'EMPTY'
AND p2.levelEl >= 1
AND e3.docID = p3.docID
AND e3.pathID = p3.pathID
AND p3.NodeName = '_PERIOD_'
AND e2.startPos < e3.startPos
AND e2.endPos > e3.endPos
AND e2.docId = e3.docId
AND p2.levelEl = p3.levelEl - 1
AND e4.docID = p4.docID
AND e4.pathID = p4.pathID
AND p4.NodeName = 'S'
AND e2.startPos < e4.startPos
AND e2.endPos > e4.endPos
AND e2.docId = e4.docId
AND p2.levelEl = p4.levelEl - 1
AND e5.docID = p5.docID
AND e5.pathID = p5.pathID
AND p5.NodeName = 'NP'
AND e4.startPos < e5.startPos
AND e4.endPos > e5.endPos
AND e4.docId = e5.docId
AND p4.levelEl = p5.levelEl - 1
AND e5.docId
= 3147524262 GROUP BY e5.docId
, e5.startPos
, e5.endPos
, p5.NodeName
, p5.levelEl
, p5.pathID
ORDER BY startPos;
正如我们所看到的,对于xpath中的每个其他节点,Iam将表元素和路径添加到 FROM 语句中,这表示该节点,有一些 where 条件来确定此节点的位置。
问题是,查询1)运行得非常快,但是对于每个新节点,sql都要慢得多。例如,查询1)需要24毫秒,但查询2)运行大约5分钟。
我添加了索引,因此查询计划仅使用索引搜索(根据Microsoft sql server)。
您是否知道如何以其他方式生成SQL查询以使执行更快?或者对现有查询(数据库表引擎等)进行一些改进?
Iam从Xpath创建TREE,看起来像这样
ROOT-ROOT (type: ROOT) False
//-EMPTY (type: NODE) False
/-_PERIOD_ (type: NODE) False
/-S (type: NODE) False
/-NP (type: NODE) True
从那棵树我生成SQL
答案 0 :(得分:4)
关于这个主题有一个lot of research,你的方法将不可避免地导致很多自连接,这很慢。它非常接近this解决方案。我建议您使用一些本地XQuery数据库,例如BaseX或Saxon,它们本身已经过优化,可以处理XQueries而无需将它们重写到SQL中。
但是,如果您真的想将XQueries重写为SQL,那么请阅读Torsten Grust提出的示例XPath accelerator。他的工作背后的想法在MonetDB XQuery engine中实施。他使用的标签方案略有不同,但我想这些想法也可以在你的方法中实现。