Sql 具有函数的查询比具有子选择的相同查询耗时更长
我有一个功能为客户获得余额 创建或替换函数default1.get_balance par_customer_id小数点31,0 返回小数点31,15 语言SQL 确定性 没有外部行动 读取SQL数据 开始 申报var_余额小数31,15; 选择SUMamount 进入var_余额 来自default1.会计 其中accounting.customer\u id=par\u customer\u id 并且YEARaccounting.accounting\u date>=YEARSYSDATE-3或accounting.accounting\u date为空 并且支付日期为空 和会计类型id 2 而且不存在 选择1 来自default1.accounting\u详细信息 其中accounting.id=detail.accounting\u id 和detail.paid_日期不为空; 返回var_余额; 终止 获取一个客户的余额的性能很好,但是在查询中使用函数一次获取多个客户的余额会变得非常慢 选择default1.get_balancecustomer.id,customer* 来自default1.customer 其中customer.id<1000 执行此查询需要2分钟以上 当我用subselect替换查询中的函数时,速度要快得多 选择 选择SUMamount 来自default1.会计 其中accounting.customer\u id=customer.id 并且YEARaccounting.accounting\u date>=YEARSYSDATE-3或accounting.accounting\u date为空 并且支付日期为空 和会计类型id 2 而且不存在 选择1 来自default1.accounting\u详细信息 其中accounting.id=detail.accounting\u id 和detail.paid_日期不为空, 顾客* 从…起 默认值1.客户 其中customer.id<1000 此查询大约需要8秒钟 我确实以不同的顺序多次执行了这两个查询,在运行时没有任何重大变化。所以我不认为这是一个缓存问题 为什么使用此函数的查询比使用subselect的查询花费的时间长约15倍?Sql 具有函数的查询比具有子选择的相同查询耗时更长,sql,db2,query-performance,stored-functions,db2-luw,Sql,Db2,Query Performance,Stored Functions,Db2 Luw,我有一个功能为客户获得余额 创建或替换函数default1.get_balance par_customer_id小数点31,0 返回小数点31,15 语言SQL 确定性 没有外部行动 读取SQL数据 开始 申报var_余额小数31,15; 选择SUMamount 进入var_余额 来自default1.会计 其中accounting.customer\u id=par\u customer\u id 并且YEARaccounting.accounting\u date>=YEARSYSDATE
在函数中有什么我可以更改以使其更快的地方吗?我假设DB2用于LUW 函数的性能可能会受到影响,因为它使用编译后的复合语句作为其主体开始。。。终止尝试使用:开始原子。。。终止更好的是,您可能只需使用RETURN语句:
CREATE OR REPLACE FUNCTION default1.get_balance (par_customer_id DECIMAL(31, 0))
RETURNS DECIMAL(31,15)
LANGUAGE SQL
NOT DETERMINISTIC
NO EXTERNAL ACTION
READS SQL DATA
RETURN SELECT SUM(amount)
INTO var_balance
FROM default1.accounting accounting
WHERE accounting.customer_id = par_customer_id
AND (YEAR(accounting.accounting_date) >= YEAR(SYSDATE)-3 or accounting.accounting_date IS NULL)
AND paid_date IS NULL
AND accounting_type_id <> 2
AND NOT EXISTS (
SELECT 1
FROM default1.accounting_detail detail
WHERE accounting.id = detail.accounting_id
AND detail.paid_date IS NOT NULL);
使用编译后的复合语句时,函数的每次调用都会导致从SQL数据访问引擎到执行引擎的上下文切换,而内联语句则成为查询计划本身的一部分
请注意,您不应该将此函数声明为确定性函数,因为它不是确定性函数;错误声明非确定性函数可能会导致意外结果。谢谢!你的两个建议都有效。我将使用带有直接返回语句的版本。