【问题标题】:join vs subquery in searches between ranges在范围之间的搜索中加入与子查询
【发布时间】:2018-09-14 20:53:51
【问题描述】:

子查询与查询的性能是一门不准确的科学,谷歌显示了两者都有优势的情况,这取决于数据结构,有必要对两者进行测试才能得出你的真相。

我有一个无法用 join 替换的子查询,并且能够测试它的性能。

假设你有一个价格历史表,你在每次价格或者它的特性变化时添加记录,举这个简单的例子:sql fiddle simple sample!

create table price_hist
( hid serial,
  product int,
  start_day date,
  price numeric,
  max_discount numeric,
  promo_code character(4) );

create table deliveries
( del_id serial,
  del_date date,
  product int,
  quantity int,
  u_price numeric);


 insert into price_hist (product, start_day,price,max_discount,promo_code) 
 values  
 (21,'2018-03-14',56.22, .022, 'Sam2'),
 (18,'2018-02-24',11.25, .031, 'pax3'),
 (21,'2017-12-28',50.12, .019, 'titi'), 
 (21,'2017-12-01',51.89, .034, 'any7'),
 (18,'2017-12-26',11.52, .039, 'jun3'),
 (18,'2017-12-10',10.99, .029, 'sep9');

insert into deliveries(del_date, product, quantity) 
values 
('2017-12-05',21,4),
('2017-12-20',18,3),
('2017-12-28',21,2),
('2018-05-08',18,1),
('2018-08-20',21,5);

select d.del_id, d.del_date, d.product, d.quantity, 
 (select price from price_hist h where h.product=d.product order by h.start_day desc limit 1) u_price, 
 (select max_discount from price_hist h where h.product=d.product order by h.start_day desc limit 1) max_discount,
 (select price from price_hist h where h.product=d.product order by h.start_day desc limit 1)*d.quantity total
 from deliveries d;

子查询查找日期范围之间的值,我无法在 postgresql 中执行相同的连接

【问题讨论】:

    标签: postgresql performance join subquery


    【解决方案1】:

    您可以使用distinct onprice_hist 获取最新的start_day 的值:

    select distinct on(product) 
        product, price, max_discount
    from price_hist h 
    order by product, start_day desc
    
     product | price | max_discount 
    ---------+-------+--------------
          18 | 11.25 |        0.031
          21 | 56.22 |        0.022
    (2 rows)
    

    将其用作派生表以将其与deliveries 连接起来:

    select 
        d.del_id, d.del_date, d.product, d.quantity, 
        h.price as u_price, h.max_discount, h.price * d.quantity as total
    from deliveries d
    join (
        select distinct on(product) 
            product, price, max_discount
        from price_hist
        order by product, start_day desc
    ) h using(product)
    

    SqlFiddle.

    【讨论】:

    • 感谢@kiin,对不起,我原来的 sqlfiddle 不完整(错误),它应该有 其中 h.product=d.product 和 h.start_day 为了达到正确的值,请检查正确的值sorry about it
    • 在这种情况下,连接效率较低,即使似乎每条记录都重复子查询
    猜你喜欢
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多