2010-07-26 44 views
2

问题到SQLite数据库引擎。我有一个相当复杂的问题,它在两组已知节点之间找到了有向图中的路径,其中只有一个节点(准确地说,是公共交通路线中的路径,但它具有图形表示形式)。SQLite - FROM子句中的表顺序会影响查询计划,为什么? (这里没有明确的加入)

现在出现了一些意想不到的问题 - 没有明确的JOIN(仅限于WHERE子句中的条件),但FROM子句中的表的排序非常影响查询计划。


对于子句

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秒


对于子句

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,但没有关于FROM表格排序。我花了几个小时来找出表现不佳的原因,但我仍然不知道发生了什么事。

这里充满问题,不是很清楚,没有表卷,但仍可能是可用的

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 

回答

0

据我所知,小SQLite的确实为查询优化主要取决于WHERE子句,并且通常是第一个WHERE子句是最赚钱的地方。

+0

在这种情况下,唯一的区别是FROM子句中的表的排序。 – tomash 2010-07-27 08:25:33

+0

我知道这是糟糕的形式,但也许最好在这种情况下询问SQLite人员自己...... – MPelletier 2010-07-28 00:57:21

相关问题