【问题标题】:sql select from a large number of IDssql 从大量ID中选择
【发布时间】:2010-06-08 22:28:05
【问题描述】:

我有一张桌子,Foo。我在 Foo 上运行查询以从 Foo 的子集中获取 id。然后我想运行一组更复杂的查询,但仅限于那些 ID。有没有一种有效的方法来做到这一点?我能想到的最好的方法是创建一个查询,例如:

SELECT ... --complicated stuff
WHERE ... --more stuff
  AND id IN (1, 2, 3, 9, 413, 4324, ..., 939393)

也就是说,我构造了一个巨大的“IN”子句。这有效率吗?是否有更有效的方法来执行此操作,或者是与获取 ID 的初始查询一起加入的唯一方法?如果有帮助,我将使用 SQLObject 连接到 PostgreSQL 数据库,并且我可以访问执行查询以获取所有 ID 的游标。

更新:我应该提到,更复杂的查询要么依赖这些 ID,要么创建更多 ID 以在其他查​​询中查找。如果我要进行一个大型查询,我最终会同时连接六个表左右,这可能太慢了。

【问题讨论】:

    标签: python sql postgresql sqlobject


    【解决方案1】:

    我过去使用的一种技术是将 ID 放入一个临时表中,然后使用它来驱动一系列查询。比如:

    BEGIN;
    CREATE TEMP TABLE search_result ON COMMIT DROP AS
      SELECT entity_id
      FROM entity /* long complicated search joins and conditions ... */;
    -- Fetch primary entities
    SELECT entity_id, entity.x /*, ... */
    FROM entity JOIN search_result USING (entity_id);
    -- Fetch some related entities
    SELECT entity_id, related_entity_id, related_entity.x /*, ... */
    FROM related_entity JOIN search_result USING (entity_id);
    -- And more, as required
    END;
    

    这在搜索结果实体具有多个一对多关系的情况下特别有用,您希望在没有 a) 执行 N*M+1 选择或 b) 执行相关实体的笛卡尔连接的情况下获取这些关系。

    【讨论】:

    • 这样做与创建临时视图有什么区别吗?
    • 视图会继续运行查询,但临时表只存储结果吗?看来我想要的是后者
    • 通过创建临时表,实际结果本身是假脱机的,因此潜在复杂的搜索只执行一次。使用临时视图,搜索条件将被转移到每个后续语句中。如果您的搜索条件很简单,则视图可能更有效。如果它们非常复杂,则将结果具体化到临时表中会胜出。我自然会从使用临时表开始,如果通过一些经验法则确定搜索条件足够简单,则可能让驱动它的应用程序使用临时视图。
    • 我是个菜鸟,但如果我在开始和结束之间有一组选择,就像在你的例子中一样,我如何真正得到结果?我尝试将查询修改为BEGIN; query; END;,但出现错误:no results to fetch
    • 你可以在这里回答,我问了一个单独的问题:stackoverflow.com/questions/3002033/…
    【解决方案2】:

    我认为使用 VIEW 可能会很有用。使用您的 ID 查询简单地创建一个视图,然后通过 ID 加入该视图。这会将您的结果限制为所需的 ID 子集,而无需使用昂贵的 IN 语句。

    我知道 IN 语句比 EXISTS 语句更昂贵。

    【讨论】:

    • 啊,这听起来正是我所需要的。是时候用谷歌搜索如何创建视图了。
    【解决方案3】:

    我认为使用选择 id 的条件进行联接会更有效,因为查询优化器有更多选项来做正确的事情。使用解释计划来查看 postgresql 将如何处理它。

    【讨论】:

    • 生病尝试解释计划。我更新到提到我最终会加入 6 张左右的桌子,这似乎需要很长时间。
    • 你永远不知道,几乎不可能预测。优化器很聪明,会使用您表中的统计信息。确保您的数据库是真空分析的。查看解释计划通常会得到一些见解,例如缺少索引或存在但未使用的索引。
    【解决方案4】:

    几乎可以肯定,使用连接会更好,但是,另一种选择是使用子选择,即

    SELECT ... --complicated stuff
    WHERE ... --more stuff
      AND id IN (select distinct id from Foo where ...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 2013-05-31
      • 1970-01-01
      • 2016-07-19
      • 2020-12-11
      • 1970-01-01
      相关资源
      最近更新 更多