SQLite - порядок таблиц в предложении FROM влияет на план запроса, почему? (здесь нет явных соединений) - PullRequest
2 голосов
/ 26 июля 2010

Вопрос к движку базы данных 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 

1 Ответ

0 голосов
/ 27 июля 2010

AFAIK, маленький SQLite для оптимизации запросов зависит главным образом от предложений WHERE, и обычно первое предложение WHERE - это то место, где нужно получить наибольшую выгоду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...