【问题标题】:Find latest timestamp in multiple tables在多个表中查找最新的时间戳
【发布时间】:2020-11-02 19:31:07
【问题描述】:

javascript 运行循环任务来监控数据库,任务(在 php 中)只是查询数据库的最新时间戳:

SELECT
    MAX(po.created)::timestamp last_purchase_order_created,
    MAX(po.modified)::timestamp last_purchase_order_modified,
    MAX(jobs.created)::timestamp last_job_created,
    MAX(jobs.modified)::timestamp last_job_modified,
    MAX(companies.created)::timestamp last_company_created,
    MAX(companies.modified)::timestamp last_company_modified,
    MAX(stock.created)::timestamp last_stock_created,
    MAX(stock.modified)::timestamp last_stock_modified
FROM purchase_orders po, jobs, companies, stock;

开始花了很长时间,因为 PHP 不是多线程的,它也阻塞了其他请求。有没有办法克服这个问题?修改后的查询,php中的不同方法,两者兼而有之?

这是问题的延续:Slow connection to Postgresql using PDO

【问题讨论】:

  • 这是因为您的选择正在执行表之间的完整产品。为避免这种情况,您必须按照某些标准加入表格

标签: php postgresql pdo


【解决方案1】:

当您这样做时,您会在所有这些表中创建一个笛卡尔积,这对您的数据库服务器要求很高。

如果您想在一个查询中执行此操作,请遵循此模式,这将为每个表提供一行:

select 'purchase_orders' as table_name, max(created) as last_created, max(modified) as last_modified 
  from purchase_orders
union all
select 'jobs', max(created), max(modified) 
  from jobs
union all
select 'companies', max(created), max(modified)
  from companies
union all
select 'stock', max(created), max(modified)
  from stock

我通常会以宿主语言(在您的情况下为 PHP)中进行转换,但如果您必须在查询中执行此操作,那么这样的事情应该可以工作:

with latest_dates as (
  select 'purchase_orders' as table_name, max(created) as last_created, max(modified) as last_modified 
    from purchase_orders
  union all
  select 'jobs', max(created), max(modified) 
    from jobs
  union all
  select 'companies', max(created), max(modified)
    from companies
  union all
  select 'stock', max(created), max(modified)
    from stock
)
select max(last_created) filter (where table_name = 'purchase_order') as last_purchase_order_created,
       max(last_modified) filter (where table_name = 'purchase_order') as last_purchase_order_modified,
       max(last_created) filter (where table_name = 'job') as last_job_created,
       max(last_modified) filter (where table_name = 'job') as last_job_modified,
       max(last_created) filter (where table_name = 'company') as last_company_created,
       max(last_modified) filter (where table_name = 'company') as last_company_modified,
       max(last_created) filter (where table_name = 'stock') as last_stock_created,
       max(last_modified) filter (where table_name = 'stock') as last_stock_modified
  from latest_dates;

【讨论】:

  • 好吧,我试试看。我不明白为什么不在 php 中这样做,除了我认为在 pgsql 方面会更快。
  • @adiDX 我通常会在 PHP 内部进行旋转,因为您可以循环遍历行并使用 table_name 动态创建数组名称。
  • 有趣的是,与我的相比,Mike 的查询运行速度快了多少 - 5 秒降低到 ~100 毫秒!关于 PostgreSQL 机制的工作原理,我还有很多东西需要了解。
【解决方案2】:

像 Mike 推荐的 UNION 查询会更好,但如果您想要快速查询,则需要在 每个 列上创建一个索引,该列有一个 max。 p>

这似乎是一个经常运行的奇怪查询。因此可以替代使用序列更好的方法吗?

如果您确实经常需要这些最大值,您可以维护一个仅包含这些最大值的特殊表,并在您插入或更新一行时进行更新。这将为您节省许多昂贵的索引。

【讨论】:

  • 谢谢你们。 UNION 是快速的临时修复。稍后我将考虑为此目的创建单独的表。 ?
  • 是的,我在想类似的东西,比如事件日志表。但是,由于您只需要每个表的最新信息,因此最好只存储和更新这些信息。
猜你喜欢
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2021-03-01
  • 2021-05-16
  • 2016-08-29
  • 1970-01-01
相关资源
最近更新 更多