2010-05-11 113 views
3

我們有一個.NET應用程序與Oracle 10g交談。我們的DBA最近拉出了一個執行等於parse_calls的查詢列表。我們假設這會幫助我們在代碼中找到所有未參數化的查詢。Oracle - 參數化查詢具有EXECUTIONS = PARSE_CALLS

沒想到,下面的查詢顯示了接近這個列表的頂部,與1436169處決和1436151個解析:

SELECT bar.foocolumn 
    FROM bartable bar, 
     baztable baz 
WHERE bar.some_id = :someId 
    AND baz.another_id = :anotherId 
    AND baz.some_date BETWEEN bar.start_date AND (nvl(bar.end_date, baz.some_date + (1/84600)) - (1/84600)) 

爲什麼處決等於parse_calls此查詢?

+1

我認爲我們需要查詢您的DBA用來確定解析呼叫計數以區分硬解析和軟解析。另外,瞭解SGA的大小將有助於消除SQL在共享池老化之前可以重用的明顯問題。 – dpbradley 2010-05-11 14:02:42

+0

我讓他再次提取查詢列表,並將解析分解爲軟和硬。 不確定SGA的大小,但我也會問他這個問題:) – 2010-05-11 14:31:02

+0

+1對所有的有趣的問答 – DCookie 2010-05-11 14:43:49

回答

3

查詢解析的次數完全取決於調用應用程序。每次應用程序要求數據庫解析時查詢都會被解析一次。

服務器端,有different kinds of parse

  • 硬解析 - 查詢從未 沒有過的,是不是在共享 池。我們必須解析它,哈希它, 看它在共享池中,不要 找到它,安全檢查它,優化 它等(大量的工作)。

  • SOFT parse - 該查詢已被 看過,在共享池中。我們 必須解析它,散列它,看在 共享池的它,發現它 (較少的工作,然後硬解析,但工作 沒有少)

最有可能在你的情況您將在每個會話中創建一次語句,然後丟棄它,以便Oracle每次都必須解析它。然而,由於參數化,這個解析是一個軟解決方案,Oracle只需要花費一次昂貴的優化步驟。

儘管如此,您也許可以將語句緩存在應用程序中並重用它,以便每次會話(軟)僅解析一次。

+0

啊,這有幫助,我認爲它回答了我在Rob的回答中的問題。每次運行查詢時,我們都會建立查詢字符串,OracleCommand對象等。 聽起來好像每次執行它都會導致軟解析。 如果我們掛在應用程序緩存中的OracleCommands中,是否會保存這些parases?掛在.NET應用程序中的數據庫資源聽起來不太好。我們總是被告知Dispose()數據庫對象,只要我們完成了它們。 – 2010-05-11 14:06:48

+0

+1爲好的解釋和建議 – 2010-05-11 14:11:13

+0

@Cory:每次你從一個字符串建立一個OracleCommand對象時,分析計數器就會上升。只有你可以判斷這項工作是多餘的。緩存最有可能執行的語句可能是一個好主意。 – 2010-05-11 14:47:47

3

可能是因爲.NET程序員都選擇在僞代碼編寫一個程序是這樣的:

Loop over someId's and anotherId's 
    parse(your_query); 
    bind someId and anotherId to your_query; 
    execute(your_query); 
    close(your_query); 
end loop; 

,他們應該已經編寫這樣的:

parse(your_query); 
Loop over someId's and anotherId's 
    bind someId and anotherId to your_query; 
    execute(your_query); 
end loop; 
close(your_query); 

甚至更​​好:使用單個查詢檢索所有someId/anotherId的所有數據

Regards, Rob。

+0

+1:最有可能的解釋 – 2010-05-11 13:59:12

+0

它看起來不像。問題中的NET代碼圍繞有問題的查詢進行循環。 我們使用System.Data.OracleClient的,做以下操作: 1.建立一個查詢字符串 2.添加參數的命令 3.執行器(是的,它應該是ExecuteScaler(),因爲我們」重新期待一個單一的價值)。 這種類型的用法是否與上面的第一個僞代碼塊一致? – 2010-05-11 14:01:29

+0

@Rob - 但是不會導致在共享池中找到SQL? – dpbradley 2010-05-11 14:04:51