改进xpath的SQL查询评估

时间:2017-10-30 12:32:11

标签: sql sql-server xml xpath sql-optimization

数据库

我有用于保存XML文档的数据库。 数据库看起来像这样:

enter image description here

所以我可以将任何XML文件保存到我的通用数据库中。

XPath查询

然后我将XPATH查询翻译成SQL查询,用于选择元素。

  • 已翻译的xpath查询示例:

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 条件来确定此节点的位置。

  • 元素有大约145 000行。
  • 路径有大约41 000行。

问题是,查询1)运行得非常快,但是对于每个新节点,sql都要慢得多。例如,查询1)需要24毫秒,但查询2)运行大约5分钟。

我添加了索引,因此查询计划仅使用索引搜索(根据Microsoft sql server)。

enter image description here

问题

您是否知道如何以其他方式生成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

1 个答案:

答案 0 :(得分:4)

关于这个主题有一个lot of research,你的方法将不可避免地导致很多自连接,这很慢。它非常接近this解决方案。我建议您使用一些本地XQuery数据库,例如BaseXSaxon,它们本身已经过优化,可以处理XQueries而无需将它们重写到SQL中。

但是,如果您真的想将XQueries重写为SQL,那么请阅读Torsten Grust提出的示例XPath accelerator。他的工作背后的想法在MonetDB XQuery engine中实施。他使用的标签方案略有不同,但我想这些想法也可以在你的方法中实现。