mar*_*ami 7 sql oracle performance plsql query-optimization
我有一个Java Web服务方法getCardInformation,可Oracle使用从数据库获取数据JDBC。每秒大约进行300个呼叫。
Java将其称为pl / sql函数:
PROCEDURE GET_CARDS_BY_ID(p_card_id IN NUMBER
,o_result OUT VARCHAR2) IS
BEGIN
SELECT 'some data'
INTO o_result
FROM 'my complicated SQL' c
WHERE c.card_id = p_card_id;
END GET_CARDS_BY_ID;
Run Code Online (Sandbox Code Playgroud)
通常SQL Select statement/procedure在30毫秒内返回结果,但有时有时需要20秒钟以上,而所有其他线程(调用)都在等待此延迟的调用。尽管这些调用没有相互连接,但是它们在SQL Select statement不同的输入参数下运行相同。所有参数都是使用Java从Java设置的bind variables。
在延迟期间,我们选择了活动会话并获得了很多游标:引脚S等待X
SELECT DISTINCT a.*, s.*
FROM V$ACTIVE_SESSION_HISTORY a
,v$sql s
WHERE a.sql_id = s.sql_id
AND blocking_session IS NOT NULL
AND a.sample_time > sysdate - 1
Run Code Online (Sandbox Code Playgroud)
我们通过添加hint到中解决了该问题Select。我们认为,在此延迟期间,Oracle试图对此进行解析Select Statement并重新计算计划,这需要一些时间。使用同一条语句的所有其他调用都等待Oracle结束计算。这就是延迟的原因。设置提示时,我们告诉oracle不要进行任何计算,因此没有延迟。
但是,为什么Oracle试图重新计算计划?
我可以在不对索引进行硬编码的情况下解决此问题吗?
当数据库中的数据量发生变化时,由于此提示,我不想更改代码。
SQL语句:
SELECT (nvl((SELECT SUM(amount)
FROM locks l
WHERE l.account = a.account),
0) - nvl((SELECT SUM(sl.amount)
FROM locks sl
,locks_2 m
WHERE sl.id = m.id
AND sl.account = a.account
AND m.text = '...'),
0)) / 100
,a.credit_limit / 100
,nvl((SELECT SUM(decode(ia.account,
ra.id,
ia.bal,
ceil(CASE
WHEN cc.ccy_num = '100' THEN
(SELECT ia.bal / r.ccy_rate
FROM my_ccy_rate r
WHERE r.ccy_num = a.account_ccy)
WHEN a.account_ccy = '100' THEN
(SELECT ia.bal * r.ccy_rate
FROM my_ccy_rates r
WHERE r.ccy_num = cc.ccy_num)
ELSE
(SELECT ia.bal * r.ccy_rate / c.ccy_rate + 15000
FROM my_ccy_rates r
,my_ccy_rates c
WHERE r.ccy_num = cc.ccy_num
AND c.ccy_num = a.account_ccy)
END)))
FROM my_v ia
,currency_codes cc
,my_table pe
WHERE ia.account = a.account_id
AND cc.ccy_alpha = ia.ccy),
0) / 100
,a.initial_amount / 100
,nvl((SELECT a.bonus_amount - nvl((SELECT SUM(sl.amount)
FROM locks sl
,locks_2 m
WHERE sl.id = m.id
AND sl.account_id = a.account_id
AND m.text = '...'),
0)
FROM my_table_1 ra
,my_accounts a
WHERE ra.centre_id = o_centre_id
AND ra.card_number = o_card
AND a.centre_id = ra.centre_id
AND a.account_id = ra.account_id),
0) / 100
INTO o_amt_1
,o_amt_2
,o_amt_3
,o_amt_4
,o_amt_5
FROM my_table_1 ra
,my_table_2 a
,my_table_3 p
WHERE ra.card_number = &card_number_input_parameter
AND a.account_id = ra.account_id;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |