视图/子查询中未使用的列(MySQL)

3
如果查询结果集没有使用由子查询或视图生成的字段,那么该字段是否仍然会被子查询处理?我的数据库中有很多视图,它们在许多地方都被使用,但所需的确切字段集因上下文而异。为了避免在每个上下文中重复相似的查询(具有适当的字段组),我一直在使用可能包含每个上下文的额外字段的视图。看起来这些额外视图会影响MySQL的性能(在下面的示例中,通过删除示例中的额外字段,我体验到了四分之一的性能提升)。有什么解决方法吗?不同的数据库(如Oracle)?
请参见下面的示例;即使在运行视图时可以明显跳过charge_off_date字段,但它仍会影响性能。
select 
    l.loan_id, last_payment_date
from
    loans as l
        left join
    (select 
        loan_id,
            max(ph.received_d) as last_payment_date,
            max(case
                when ph.co = 1 then coalesce(ph.received_d, ph.month)
                else null
            end) as charge_off_date
    from
        payment_history as ph) as payment_stats ON payment_stats.loan_id = l.loan_id

如果有人欠钱,他们支付$1并将最后付款日期推迟,这对他们有任何好处吗? - William Entriken
我们能看到 SHOW CREATE TABLEEXPLAIN SELECT ... 吗? - Rick James
1个回答

1
MySQL实例化(非相关)子查询并为视图创建执行计划,但不会对视图进行优化。换句话说,在这种情况下,MySQL不会进行优化。
其他数据库在优化方面更加聪明。这并不意味着它们会做正确的事情,但有机会。
我建议您将查询编写为只有连接和聚合而没有子查询的join形式。
select l.loan_id, max(ph.received_d) as last_payment_date,
       max(case when ph.co = 1 then coalesce(ph.received_d, ph.month)
           end) as charge_off_date
from loans l left join
     payment_history ph
     on ph.loan_id = l.loan_id
group by l.loan_id;

在MySQL视图中,不需要在from子句中使用子查询(这是不允许的)。另外,如果你有一个where子句,应该利用它并提高性能。请注意,保留html标签。

谢谢。我对这个方法的担忧有两点:首先,这会导致重复,因为计算出的列可能需要被其他计算重用。例如,您可以计算 days_since_chargeoff 和 loan_duration_until_chargeoff。这些都需要重新定义 charge_off_date。其次,如果任何不同的表需要使用 charge_off_date,则不再存在单一的一致计算。相反,它们需要每次加入和重新计算 charge_off_date。因此,似乎在额外字段和冗余计算/定义之间存在权衡。 - jgood408
1
这种方法不太通用,因为使用 SELECT #COLUMNS# FROM #VIEW# WHERE #CONDITIONS#,您可以轻松地让报告应用程序生成 #COLUMNS##CONDITIONS# - William Entriken
@WilliamEntriken - 将您的评论提升为答案。 - Rick James
@RickJames……William在这个问题上悬赏了。我不认为他试图回答它。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接