Оптимальный способ объединения трех таблиц в SQLite - PullRequest
8 голосов
/ 10 ноября 2010

(упрощенная) база данных интернет-закладок.Я подумал, что имеет смысл организовать таблицы логически, например так:

Bookmarks (id, title, url; basically external data)
+------+------------+-----+
| suid |   Title    | ... |
+------+------------+-----+

User (user-specific data: favorites, ratings, etc)
+------+------------+-----+
| suid | IsFavorite | ... |
+      +  (0 or 1)  +     +
+------+------------+-----+

History (last used, use count etc)
+------+------------+-----+
| suid |  LastUsed  | ... |
+      +(TDateTime) +     +
+------+------------+-----+

('suid' - уникальный идентификатор, целочисленный первичный ключ)

Из закладок, помеченных как избранное Мне нужно выбрать N последнее использованное (для удобства меню во время выполнения).

SELECT Bookmarks.suid, Title from Bookmarks
    INNER JOIN User USING (suid)
    INNER JOIN History USING (suid)
    WHERE IsFavorite = 1
    ORDER BY LastUsed DESC
    LIMIT 15;

Оператор работает и кажется достаточно читабельным, ноэто оптимально?Таблица закладок предназначена для хранения в среднем 20-50 тыс. Записей (т. Е. Не стандартного менеджера закладок в браузере :-) При запуске приложение выполнит 3 или 4 аналогичных оператора, чтобы заполнить элементы управления.Все поля, используемые в примере, проиндексированы.

Я учу себя SQL и придумал приведенный выше код, но, возможно, я пропускаю синтаксис или идиому, которая могла бы его улучшить?

Ответы [ 3 ]

6 голосов
/ 12 ноября 2010

Невозможно (или, по крайней мере, очень, очень сложно) угадать из необработанного SQL, как именно движок базы данных будет выполнять запрос.По этой причине вам нужно использовать EXPLAIN, чтобы узнать, как SQLite будет на самом деле получать данные.И имейте в виду, что сгенерированный план выполнения будет отличаться в зависимости от того, сколько данных в каждой таблице и как они выглядят (с точки зрения количества различных значений, найденных в индексированных столбцах).Поэтому убедитесь, что ваша тестовая база данных заполнена реально выглядящими данными.

Как только вы попробуете EXPLAIN, я думаю, что вы обнаружите, что SQLite объединяет таблицы вместе, прежде чем взять 15 лучших совпадений,будет неоптимальным, если это правда.Если это так, вы можете попробовать что-то вроде:

SELECT Bookmarks.suid, Title from Bookmarks
  INNER JOIN User USING (suid)
  WHERE IsFavorite = 1
  AND suid IN (SELECT suid FROM History ORDER BY LastUsed DESC LIMIT 15);

Но, опять же, не пытайтесь делать это, пока вы не увидите из EXPLAIN, что SQLite получает данные воптимальным образом.

0 голосов
/ 12 ноября 2010

Вы можете использовать ключевое слово EXPLAIN, как уже говорилось, но есть и другие способы улучшить его. Есть веб-сайт с некоторой информацией ... проверьте его, нажав здесь , чтобы узнать больше об этом ... удачи!

0 голосов
/ 10 ноября 2010

Это выглядит нормально для меня. Возможно, вы уже знаете это, но можете исследовать свой запрос, используя ключевое слово объяснения (http://www.sqlite.org/lang_explain.html), если хотите настроить его дальше.

Ура! * * 1004

...