Вопрос к движку базы данных SQLite. У меня довольно сложный вопрос, который находит путь в ориентированном графе между двумя наборами известных узлов, с ровно одним узлом между ними (точнее, путь в маршрутах общественного транспорта, но он имеет представление графа).
Теперь что-то неожиданное - нет явных рассматриваемых 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, но ничего не упорядочено. Мне понадобилось несколько часов, чтобы выяснить причину плохой работы, и я до сих пор не знаю, что случилось.
Вот полный вопрос, не очень понятный и без табличных томов, но все еще пригодный для использования
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