代码之家  ›  专栏  ›  技术社区  ›  Marek Jedliński

SQLite中三表连接的优化方法

  •  8
  • Marek Jedliński  · 技术社区  · 14 年前

    因特网书签的(简化的)数据库。我认为合理地组织表格是有意义的,比如:

    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) +     +
    +------+------------+-----+
    

    从标记为的书签 我需要选择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;
    

    这个语句有效,而且看起来可读性很强,但是它是最佳的吗?Bookmarks表的目的是平均保存20-50k条记录(即,不是您的标准浏览器书签管理器:-),应用程序将在启动时执行3或4个类似的语句来填充控件。示例中使用的所有字段都被索引。

    我在自学SQL,并提出了上述代码,但也许我忽略了一个语法或习惯用法,可以改进它?

    3 回复  |  直到 14 年前
        1
  •  6
  •   Larry Lustig    14 年前

    从原始SQL中不可能(或者至少非常非常难)准确猜测数据库引擎将如何满足查询。因此,您需要使用EXPLAIN来了解SQLite将如何实际获取数据。并且要注意,它生成的执行计划将根据每个表中有多少数据以及数据的“外观”而有所不同(根据索引列中找到的不同值的数量)。所以一定要用真实的数据来充实你的测试数据库。

    一旦您尝试解释,我认为您可能会发现SQLite在进行前15个匹配项之前将表连接在一起,如果为true,这将是非最优的。如果是这样的话,你可以尝试一下:

    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);
    

        2
  •  0
  •   Lefteris Laskaridis    14 年前

    我看没问题。您可能已经知道这一点,但是如果您想进一步优化查询,可以使用explain关键字(http://www.sqlite.org/lang_explain.html)来调查查询。

    干杯!

        3
  •  0
  •   Lu4nation    14 年前

    有一个网站有一些信息。。。看看吧,clickin' here 想了解更多。。。 祝你好运!