哪吒2之魔童闹海|哪吒2之魔童归来免费观看|哪吒2在线观看|哪吒2魔童闹海电影免费观看|哪吒2免费观看完整版大电影|哪吒1免费观看完整版

新疆軟件開(kāi)發(fā)

本站首頁(yè) 軟件開(kāi)發(fā) 成功案例 公司新聞 公司簡(jiǎn)介 客服中心 軟件技術(shù) 網(wǎng)站建設(shè)
  您現(xiàn)在的位置: 新疆二域軟件開(kāi)發(fā)公司 >> 開(kāi)發(fā)語(yǔ)言 >> 文章正文

Oracle為何找不準(zhǔn)確索引?解決Oracle.DataAccess的問(wèn)題

           服務(wù)器為Oracle 9i,NHibernate使用NHibernate.Driver.OracleDataClientDriver(Oracle.DataAccess.dll,使用ODTwithODAC1020221這個(gè)版本安裝。因?yàn)檎讲渴鸫蛩阌肙racle 10g,所以客戶端NHibernate用了這個(gè)驅(qū)動(dòng),另外也是為了避免System.Data.OracleClient.dll操作Clob/Nclob時(shí)的問(wèn)題),陸續(xù)發(fā)現(xiàn)不少奇怪的問(wèn)題。不清楚是這個(gè)驅(qū)動(dòng)跟Oracle 9i之間的兼容性造成還是其它原因,不過(guò)最終基本都解決了。 
1. 今天解決了2個(gè)性能方面的問(wèn)題,原因都是日期類型的字段造成。 
1.1 第一個(gè)查詢是對(duì)一個(gè)60多萬(wàn)的表執(zhí)行單表查詢,有一個(gè)日期字段建了索引,查詢會(huì)使用這個(gè)日期字段。一開(kāi)始查詢很慢,估計(jì)是NHibernate生成的SQL語(yǔ)句沒(méi)有使用到索引(把日志中的SQL語(yǔ)句拿出來(lái)分析,查詢計(jì)劃中顯示是使用了索引的)。解決方法是按照使用NHibernate, Oracle Clob/NClob無(wú)法插入、亂碼問(wèn)題的方式創(chuàng)建一個(gè)用戶自定義日期類型,將IDbCommand中對(duì)應(yīng)參數(shù)的OracleDbType設(shè)置為OracleDbType.Date,然后在NHibernate中把日期字段配置為這個(gè)類型。這樣查詢就能使用到索引了。

1.2 跟第一個(gè)問(wèn)題基本類似。
也是一個(gè)查詢,涉及到多個(gè)表的關(guān)聯(lián),有個(gè)表數(shù)據(jù)400多萬(wàn)。同樣估計(jì)是一個(gè)日期字段的索引沒(méi)有發(fā)揮作用而導(dǎo)致的低效(同樣,SQL語(yǔ)句抓出來(lái)用查詢計(jì)劃分析,顯示索引是使用上了),但是按照1.1中的方法之后還是不起作用。唯一不同之處是1.1用的ICriteria,而這個(gè)查詢用的是IQuery。
解決方法是把sql改成類似b.CreateDate>to_date(:startDate, ’YYYY-MM-DD’)這種形式,然后使用IQuery.SetString()方法而不是IQuery.SetDateTime(),這樣就OK了。

第一個(gè)問(wèn)題還好理解,如果參數(shù)類型沒(méi)有設(shè)置正確無(wú)法利用索引,比較正常,但這個(gè)方法無(wú)法運(yùn)用在第二個(gè)類似的問(wèn)題上就比較費(fèi)解了。

2. 用Oracle.DataAccess 10.2這個(gè)版本調(diào)用Oracle 9i的Function/Procedure時(shí)問(wèn)題比較多。
2.1 正常情況下調(diào)用應(yīng)當(dāng)是這個(gè)樣子:
OracleConnection con = new OracleConnection("connection string"); 
con.Open(); 
OracleCommand cmd = con.CreateCommand(); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.CommandText = "function / procedure name"; cmd.Parameters.Add(new OracleParameter("param name", OracleDbType.Double).Value = 12.1); 
int effectedRows = cmd.ExecuteNonQuery(); 
con.Close();
但在Oracle 9i上函數(shù)或存儲(chǔ)過(guò)程聲明的參數(shù)類型為Number(老系統(tǒng)的東西,不敢改動(dòng)),而ODAC 10.2的OracleDbType是沒(méi)有Number這個(gè)類型的,把參數(shù)設(shè)置成OracleDbType.Double、OracleDbType.Decimal等各種類型,均報(bào)錯(cuò)無(wú)法轉(zhuǎn)換成數(shù)字類型。
只有改成下面這種方式才能成功調(diào)用:
OracleConnection con = new OracleConnection("connection string"); 
con.Open(); 
OracleCommand cmd = con.CreateCommand(); 
cmd.CommandType = CommandType.Text; 
cmd.CommandText = @" 
Declare v_value Number; 
    Begin v_value:=function or procedure name(:p1, :p2, :returnValue); 
End;"; 
cmd.Parameters.Add(new OracleParameter("p1", OracleDbType.Double).Value = 12.1); 
cmd.Parameters.Add(new OracleParameter("p2", OracleDbType.Varchar2).Value = "Test"); 
cmd.Parameters.Add(new OracleParameter("returnValue", OracleDbType.Int32, ParameterDirection.Output).Value = 0); 
int effectedRows = cmd.ExecuteNonQuery(); 
con.Close();
if (cmd.Parameters[2].Value != null && cmd.Parameters[2].Value != DBNull.Value) 

    int returnValue = Convert.ToInt32(cmd.Parameters[2].Value); 
    /*....*/
}

2.2 如果Function/Procedure有out型的參數(shù),參數(shù)類型為Varchar2等字符串型的,必須指定參數(shù)的Size屬性,否則報(bào)緩沖區(qū)溢出錯(cuò)誤。

3. 極個(gè)別的情況下,客戶端已經(jīng)把一條數(shù)據(jù)刪除了,用SQL查詢數(shù)據(jù)庫(kù)確實(shí)查不到這條數(shù)據(jù),但是NHibernate仍然能夠獲取到這個(gè)對(duì)象。
確認(rèn)NHibernate沒(méi)有開(kāi)二級(jí)緩存;確認(rèn)NHibernate有向服務(wù)器提交這個(gè)SQL語(yǔ)句,跟蹤到NHibernate,在執(zhí)行DbCommand查詢時(shí)生成的SQL語(yǔ)句正確,參數(shù)設(shè)置正確,日志中記錄的這些也是正確的,但NHibernate執(zhí)行完之后的確返回了這條數(shù)據(jù);監(jiān)控?cái)?shù)據(jù)庫(kù)服務(wù)器,確認(rèn)服務(wù)器根本沒(méi)有執(zhí)行這個(gè)SQL。所以把問(wèn)題確定在ODAC 10.2這個(gè)驅(qū)動(dòng)上面。但更奇怪的是客戶端(Web Server,上面配置了Oracle網(wǎng)絡(luò)服務(wù))重起機(jī)器,問(wèn)題還在;數(shù)據(jù)庫(kù)服務(wù)器重起機(jī)器,問(wèn)題還在,還能查出那條數(shù)據(jù)。后來(lái)再?zèng)]有發(fā)生這種情況,也無(wú)從查起。

2008.01.06
上面兩個(gè)問(wèn)題都是Oracle沒(méi)有找準(zhǔn)索引,從程序?qū)用鎸?shù)信息設(shè)置準(zhǔn)確確實(shí)比較重要。
另外優(yōu)化過(guò)程中不斷發(fā)現(xiàn)Oracle找不準(zhǔn)索引的情況,在不少查詢中添加了指定索引,甚至是JOIN TYPE的hints,倒忘了另外一個(gè)重要方面:測(cè)試庫(kù)經(jīng)常大量的導(dǎo)入測(cè)試數(shù)據(jù),需要分析維護(hù)Oracle索引!

作者:未知 | 文章來(lái)源:未知 | 更新時(shí)間:2008-2-18 10:49:26

  • 上一篇文章:

  • 下一篇文章:

  • 相關(guān)文章:
    Orcale與Asp.net的端口沖突解決方法
    軟件技術(shù)
    · 開(kāi)發(fā)語(yǔ)言
    · Java技術(shù)
    · .Net技術(shù)
    · 數(shù)據(jù)庫(kù)開(kāi)發(fā)
    最新文章  
    ·搜集整理的asp.net的驗(yàn)證方
    ·各種FOR循環(huán)結(jié)構(gòu)的整理
    ·軟件項(xiàng)目開(kāi)發(fā)中應(yīng)該考慮那
    ·搜集整理的javascript sel
    ·軟件開(kāi)發(fā)中項(xiàng)目經(jīng)理有那些
    ·學(xué)習(xí)如何在Lambda表達(dá)式進(jìn)
    ·C++基礎(chǔ)知識(shí):結(jié)構(gòu)體數(shù)據(jù)的
    ·C#實(shí)現(xiàn)短信發(fā)送程序的例子
    ·sun最近修補(bǔ)了一部分java的
    ·rss定制的另外一種實(shí)現(xiàn)方式
    ·delphi實(shí)現(xiàn)利用arp欺騙來(lái)實(shí)
    ·基礎(chǔ)學(xué)習(xí):基于WF的流程框
    ·網(wǎng)絡(luò)編程中怎樣得知一次數(shù)
    ·如何逆序輸出單鏈表?
    ·軟件開(kāi)發(fā)過(guò)程中的性能設(shè)計(jì)
    關(guān)于我們 | 軟件開(kāi)發(fā) | 下載試用 | 客服中心 | 聯(lián)系我們 | 友情鏈接 | 網(wǎng)站地圖 | 新疆電子地圖 | RSS訂閱
    版權(quán)所有 © 2016 新疆二域軟件開(kāi)發(fā)網(wǎng) www.pg11qqq.com All Rights Reserved 新ICP備14003571號(hào)
    新疆軟件開(kāi)發(fā)總機(jī):0991-4842803、4811639.
    客服QQ:596589785 ;地址:新疆烏魯木齊北京中路華聯(lián)大廈A-5C 郵編:830000