代码之家  ›  专栏  ›  技术社区  ›  Chase Lundell

XQY查询运行方式减慢了从lahman Basketball数据库连接两个大表的速度

  •  1
  • Chase Lundell  · 技术社区  · 6 年前

    我正在使用拉曼棒球数据库进行一个关于比较不同查询技术的项目。我已经在SQL中执行了一系列查询,然后使用SQL workbench将表移植到XML文件。然后我将它们上传到existdb服务器上,并尝试在其上运行查询,但速度太慢了。 我有一个称为外观的xml文件。看起来像这样的xml。但是,它有98146行元素。

    <appearances>
    <ROW>
        <yearID>1871</yearID>
        <teamID>BS1</teamID>
        <lgID>NA</lgID>
        <masterID>barnero01</masterID>
    </ROW>
    <ROW>
        <yearID>1871</yearID>
        <teamID>BS1</teamID>
        <lgID>NA</lgID>
        <masterID>barrofr01</masterID>
    </ROW>
    </appearances>
    

    我还有一个名为master的xml文件。看起来像这样的xml,它有18354个行元素。

    <master>
    <ROW>
        <masterID>aardsda01</masterID>
        <nameFirst>David</nameFirst>
        <nameLast>Aardsma</nameLast>
    </ROW>
    <ROW>
        <masterID>aaronha01</masterID>
        <nameFirst>Hank</nameFirst>
        <nameLast>Aaron</nameLast>
    </ROW>
    </master>
    

    我正在尝试运行一个XQY查询来连接这两个表,并找到每个teamID为“LAN”的条目的名字和姓氏。

    let $laPlayers := for $appearance in /appearances/ROW
              let $player := /master/ROW/masterID=$appearance/masterID
              where $appearance/teamID eq "LAN"
              return fn:concat($player/nameFirst/text(),' ', 
    $player/nameLast/text())
    
    return $laPlayers
    

    它跑得很好,但速度太慢了!在外观表中,每个masterID都有多个条目,因为yearID(我在这里不使用),所以我尝试先调用不同的值。

    let $laIds = fn:distinct-values(for $appearance in /appearances/ROW
                  where $appearance/teamID eq "LAN"
                  return $appearance/masterID/text())
    let $laPlayers = for $player in /master/ROW
                  for $id in $laIds
                  where $id eq $player/masterID
                  order by $player/nameLast
                  return fn:concat($player/nameFirst/text(),' ', 
    $player/nameLast/text())
    
    return $laPlayers
    

    这使得它的速度更快,但仍然比它的SQL等价物慢得多。我能做些什么来加快速度吗? (以下是SQL等效项)

    SELECT DISTINCT m.nameFirst, m.nameLast FROM appearances a, master m 
    WHERE a.teamID = "LAN" AND a.masterID = m.masterID ORDER BY m.nameLast, m.nameFirst;
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Joe Wicentowski    6 年前

    您的查询将受益于 <teamID> <masterID> 元素,因为索引允许数据库仅对索引值执行快速查找,而不是在所有数据中扫描请求的元素和值。要配置这样的索引,请创建如下集合配置文档:

    <collection xmlns="http://exist-db.org/collection-config/1.0">
        <index xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <range>
                <create qname="teamID" type="xs:string"/>
                <create qname="masterID" type="xs:string"/>
            </range>
        </index>
    </collection>
    

    保存此文档并命名 collection.xconf ,将其放置在 /db/system/config 对应于包含数据的集合。例如,如果您的数据位于 /db/apps/my-app/data ,然后保存 收集xconf公司 文件位于 /db/system/config/db/apps/my-app/data

    以下是有关范围索引和更广泛主题的现有文档的链接,在您学习的过程中会对您有所帮助: