powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / SQLite [игнор отключен] [закрыт для гостей] / SQLite: Как правильно готовить LEFT OUTER JOIN ?
9 сообщений из 9, страница 1 из 1
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #35982308
agakhov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день,
к сожалению я не профи в по работе с бд, заранее извиняюсь если вопрос тривиальный.

работаю с sqlite встроенной в adobe air

Столкнулся с очень низкой производительностью запроса на базе конструкции LEFT OUTER JOIN.
Интерес вызван тем, что в документации рекомендуется использовать именно JOIN и избегать подзапросов и IN
Возможно я не правильно готовлю LEFT OUTER JOIN.

Иходные таблицы:
1) Groups - (в запросе не участвует привидена для общей картины) , 2000 строк

2) Devices - (устройства) , 30000 строк
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
		
CREATE TABLE IF NOT EXISTS Devices 
(
id INTEGER NOT NULL PRIMARY KEY UNIQUE,
name VARCHAR( 45 ) default NULL,
...(примерно  50  полей свойств) 
)

3) DeviceDetails - таблица связей. Один device может входить в несколько групп. 80000 строк
Код: plaintext
1.
2.
3.
4.
5.
6.
			
CREATE TABLE IF NOT EXISTS DeviceDetails
(
deviceId INTEGER NOT NULL,
groupId INTEGER NOT NULL
)

Задача получить девайсы (Device) по заданной группе.

Конструкция с JOIN на рутовой группе отрабатывает 38 секунд (результат 14000 элементов):
Код: plaintext
1.
2.
3.
SELECT * FROM Devices as d LEFT OUTER JOIN DeviceDetails as a
ON a.deviceId = d.id 
WHERE a.groupId = :groupId
Конструкция с подзапросом отрабатывает 2 секунды:
Код: plaintext
1.
2.
SELECT * FROM Devices WHERE id in(
SELECT deviceId from DeviceDetails WHERE groupId = :groupId)

добавление индексов, ощутимого прироста производитьльности не даёт.
Код: plaintext
1.
2.
3.
4.
5.
CREATE INDEX IF NOT EXISTS GroupIndex
on DeviceDetails (groupId);

CREATE INDEX IF NOT EXISTS DeviceIndex
on DeviceDetails (deviceId);

Буду благодарен если поможете прояснить ситуацию.
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #35982495
Bard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сначала попробуй
Код: plaintext
1.
ANALYZE Devices
ANALYZE DeviceDetails
и запрос, по-моему, у тебя должен выглядеть так :
Код: plaintext
1.
2.
3.
SELECT *
FROM DeviceDetails as a
   INNER JOIN Devices as d ON a.deviceId = d.id 
WHERE a.groupId = :groupId
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #35983748
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
agakhovЗадача получить девайсы (Device) по заданной группе. Здесь действительно нужен inner а не outer join.
Можно сделать как уже показал Bard, а можно перевернуть порядок таблиц и сделать вот так:
Код: plaintext
1.
2.
SELECT *
FROM Devices as d
   INNER JOIN DeviceDetails as a ON a.deviceId = d.id and a.groupId = :groupId
Подобный запрос обычно более эффективен чем фильтрующий после соединения таблиц.
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #35983962
agakhov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Bard, White Owl

смысл комадны ANALYZE,  я не осознал. Возможно её нужно запускать из командной строки. По крайней мере все GUI инструменты по работе с sqlite, молча её выполнили, оставив меня в неведении о происходящем.


Данный запрос у меня работает 1656 ms, что гораздо лучше чем OUTER JOIN и сравнимо с подзапросом(953ms)
Код: plaintext
1.
2.
3.
4.
SELECT *
FROM DeviceDetails as a
   INNER JOIN Devices as d ON a.deviceId = d.id 
WHERE a.groupId = :groupId

Вариант OUTER JOIN и без Where отрабатывает быстрее(653ms) чем конструкция с подзапросом(953ms), за что отдельная благодарность White Owl
Код: plaintext
1.
2.
3.
SELECT *
FROM Devices as d
   INNER JOIN DeviceDetails as a ON a.deviceId = d.id and a.groupId = :groupId

p/s
Вернулась вера в документацию, буду изучать матчасть по работе с конструкцией JOIN.
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #35985363
Bard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
agakhovсмысл комадны ANALYZE,  я не осознал. Возможно её нужно запускать из командной строки. По крайней мере все GUI инструменты по работе с sqlite, молча её выполнили, оставив меня в неведении о происходящем.sb-news.netКоманда ANALYZE собирает статистику о индексах и их хранении в специальных таблицах базы данных, когда оптимизатор запросов может использовать их для выбора лучших индексов.На больших объемах при использовании индексов весьма полезная команда. Обычно выполняется после вставки/изменении большого объёма данных. См. ANALYZE

White OwlПодобный запрос обычно более эффективен чем фильтрующий после соединения таблиц.Век живи...
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #36213206
Oleg Zhovtanyuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
Код: plaintext
1.
2.
SELECT *
FROM Devices as d
   INNER JOIN DeviceDetails as a ON a.deviceId = d.id and a.groupId = :groupId
Подобный запрос обычно более эффективен чем фильтрующий после соединения таблиц.

Спасибо!
Действительно, джойны без where быстрее...
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #36213812
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
Смотрите

Код: plaintext
explain query plan _запрос_

Эта команда покажет, какие таблицы и индексы используются. Еще была в сети презенташка от DRH, кажется, 2004-го года, где было подробно расписано, как работает планировщик в эскулайт - он полностью детерминирован, так что вы можете заранее оценить план выполнения запроса. Также бывает полезно при выборках пользоваться конструкцией indexed by, чтобы планировщик использовал именно указанный вами индекс (если это невозможно, будет сгенерирована ошибка).
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #38465950
vik.kz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl,

объясните, что означает a.groupId = :groupId в вашем примере?
...
Рейтинг: 0 / 0
SQLite: Как правильно готовить LEFT OUTER JOIN ?
    #38466736
vik.kz,

сравнение поля таблицы (a.groupId) с переменной подстановки (:groupId). Значение переменной передается в запрос из внешней (вызываемой) среды.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / SQLite: Как правильно готовить LEFT OUTER JOIN ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]