【问题标题】:Is count() the most efficient way to count the number of objects?count() 是计算对象数量的最有效方法吗?
【发布时间】:2018-10-17 17:43:16
【问题描述】:

我需要计算数据库中特定模型的对象数量,并使用上下文处理器显示该数量,以便用户在每个页面上查看。

现在我只是在做Model.objects.count()。它可以工作,但由于数据库中现在有超过 400,000 个对象,它明显减慢了速度。

我在我的开发服务器上运行,所以也许一旦我推送到专用服务器这不会成为问题,但我不确定......我担心一旦我们达到数百万会发生什么或超越。有什么建议吗?

【问题讨论】:

  • 这更多地取决于数据库引擎。 COUNT(*) FROM table 可以像 O(1) 一样快,这意味着元素的数量无关紧要:stackoverflow.com/a/5258011/67579
  • 在 postgresql 中计数为 O(N)。您真的需要每个请求的确切行数吗?
  • @soon 添加参考:postgresqltutorial.com/postgresql-count-function。它基本上写在文本的第一行。 When you apply the COUNT(*) function to the entire table, PostgreSQL has to scan the whole table sequentially. If you use the COUNT(*) function on a big table, the query will be slow. This is related to the PostgreSQL MVCC implementation.
  • 此外...如果不需要确切的数字,您可以进行估算,请参见此处:wiki.postgresql.org/wiki/Count_estimate

标签: python django postgresql count


【解决方案1】:

如果您从pg_class.reltuples 得到的估计足够好,那就去吧。那将是最简单的解决方案。

如果您需要确切的数字,可以使用触发器来完成。以下示例在mytab_count 中保留表mytab 的计数:

CREATE TABLE mytab_count (
   c bigint NOT NULL
);  

-- make sure there cannot be more than one row
CREATE UNIQUE INDEX mytab_count_singleton
   ON mytab_count ((1));

INSERT INTO mytab_count
   SELECT count(*) FROM mytab;

CREATE OR REPLACE FUNCTION count_trig() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   CASE TG_OP
      WHEN 'INSERT' THEN
         UPDATE mytab_count SET c = c + 1;
         RETURN NEW;
      WHEN 'DELETE' THEN
         UPDATE mytab_count SET c = c - 1;
         RETURN OLD;
   END CASE;
END;$$;

CREATE TRIGGER count_trig AFTER INSERT OR DELETE ON mytab
   FOR EACH ROW EXECUTE PROCEDURE count_trig();

【讨论】:

    猜你喜欢
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2011-01-26
    相关资源
    最近更新 更多