代码之家  ›  专栏  ›  技术社区  ›  tomash

FROM子句中的sqlite-table顺序会影响查询计划,为什么?(此处没有显式联接)

  •  2
  • tomash  · 技术社区  · 15 年前

    对SQLite数据库引擎的问题。我有一个相当复杂的问题,它在两组已知节点之间的有向图中找到路径,其中只有一个节点介于两者之间(准确地说,公共交通路线中的路径,但它有图表示)。

    现在出现了一些意想不到的情况——没有明确的连接存在问题(只有WHERE子句中的条件),但是FROM子句中表的顺序对查询计划影响很大。


    FOR子句

    from przystanek skad, przystanek dokad, linia l1, linia l2, przystanek posredni1, przystanek posredni2
    from KNOWN_START_NODE, KNOWN_END_NODE, unknown_arc1, unknown_arc1, unknown_node_middle1, unknown_node_middle2
    

    查询计划为:

    TABLE linia AS l1 WITH INDEX linia_id_miasto
    TABLE przystanek AS skad WITH INDEX przystanek_id_linia
    TABLE linia AS l2 WITH INDEX linia_id_miasto
    TABLE przystanek AS dokad WITH INDEX przystanek_id_linia
    TABLE przystanek AS posredni1 WITH INDEX przystanek_id_linia
    TABLE przystanek AS posredni2 WITH INDEX przystanek_linia_nrprzystanku
    

    查询需要0.14秒


    FOR子句

    from linia l1, linia l2, przystanek posredni1, przystanek posredni2, przystanek skad, przystanek dokad
    from unknown_arc1, unknown_arc1, unknown_node_middle1, unknown_node_middle2, KNOWN_START_NODE, KNOWN_END_NODE
    

    查询计划为:

    TABLE linia AS l1 WITH INDEX linia_id_miasto
    TABLE linia AS l2 WITH INDEX linia_id_miasto
    TABLE przystanek AS posredni1 WITH INDEX przystanek_id_linia
    TABLE przystanek AS posredni2 WITH INDEX przystanek_linia_nrprzystanku
    TABLE przystanek AS skad WITH INDEX przystanek_id_linia
    TABLE przystanek AS dokad WITH INDEX przystanek_id_linia
    

    查询需要4.90秒


    为什么会有这样的差异?我读过了 http://www.sqlite.org/optoverview.html 但是,从表格排序中没有任何内容。我花了几个小时才找到表现不佳的原因,但我仍然不知道发生了什么。

    这里有一个完整的问题,不太清楚,没有表卷,但仍然可以使用

    select 
    l1.nazwapliku, 
    l2.nazwapliku, 
    posredni1.nrprzystanku as nrposr,
    skad.kolejnosc as k1a, 
    posredni1.kolejnosc as k1b, 
    posredni2.kolejnosc as k2a, 
    dokad.kolejnosc as k2b,
    skad.nrprzystanku, 
    dokad.nrprzystanku
    
    from przystanek skad, przystanek dokad, linia l1, linia l2, przystanek posredni1, przystanek posredni2
    where 
    
    skad.nrprzystanku IN (1) AND
    dokad.nrprzystanku IN (2) AND
    
    l1.id_miasto = 1 AND
    l2.id_miasto = 1 AND
    l1._id <> l2._id AND
    l1.nazwalinii <> l2.nazwalinii AND
    posredni1._id<>posredni2._id AND
    
    skad.id_linia = l1._id AND
    posredni1.id_linia = l1._id AND
    skad.kolejnosc<posredni1.kolejnosc AND
    
    posredni1.nrprzystanku=posredni2.nrprzystanku AND
    posredni2.id_linia = l2._id AND
    dokad.id_linia = l2._id AND
    
    posredni2.kolejnosc<dokad.kolejnosc 
    
    1 回复  |  直到 15 年前
        1
  •  0
  •   MPelletier    15 年前

    对于查询优化,sqlite所做的一点工作主要取决于WHERE子句,通常第一个WHERE子句是获得最大收益的地方。

    推荐文章