oracle分頁(yè)查詢(xún)效率最高 oracle分頁(yè)公式
夕逆IT
- 前端設(shè)計(jì)
- 2023-08-13 11:40:10
- 93

大家好,今天小編來(lái)為大家解答oracle分頁(yè)查詢(xún)效率最高這個(gè)問(wèn)題,oracle分頁(yè)公式很多人還不知道,現(xiàn)在讓我們一起來(lái)看看吧!oracle游標(biāo)的使用詳解Oracle游標(biāo)...
大家好,今天小編來(lái)為大家解答oracle分頁(yè)查詢(xún)效率最高這個(gè)問(wèn)題,oracle分頁(yè)公式很多人還不知道,現(xiàn)在讓我們一起來(lái)看看吧!
oracle游標(biāo)的使用詳解
Oracle游標(biāo)(Cursor)是Oracle數(shù)據(jù)庫(kù)中用于執(zhí)行SQL查詢(xún)的對(duì)象。它允許用戶(hù)在查詢(xún)結(jié)果中快速跳轉(zhuǎn)到所需的數(shù)據(jù)行。以下是Oracle游標(biāo)的詳細(xì)使用說(shuō)明:
聲明游標(biāo):在執(zhí)行SQL查詢(xún)前,需要先聲明游標(biāo)??梢允褂肈ECLARE語(yǔ)句來(lái)聲明游標(biāo),例如:
sql復(fù)制DECLARE
CURSORmy_cursorIS
SELECTcolumn1,column2,column3
FROMmy_table
WHEREsome_condition;
這里,my_cursor是聲明的游標(biāo)名稱(chēng),my_table是要查詢(xún)的表名,column1,column2,column3是要從表中檢索的列名。
打開(kāi)游標(biāo):在聲明游標(biāo)后,需要使用OPEN語(yǔ)句打開(kāi)游標(biāo)。例如:
sql復(fù)制OPENmy_cursor;
這將打開(kāi)名為my_cursor的游標(biāo)。
讀取游標(biāo):使用FETCH語(yǔ)句可以從游標(biāo)中讀取數(shù)據(jù)。例如:
sql復(fù)制FETCHNEXTFROMmy_cursorINTO@column1,@column2,@column3;
這將從名為my_cursor的游標(biāo)中讀取下一行數(shù)據(jù),并將其存儲(chǔ)在@column1、@column2和@column3變量中。
關(guān)閉游標(biāo):在使用完游標(biāo)后,需要使用CLOSE語(yǔ)句關(guān)閉游標(biāo)。例如:
sql復(fù)制CLOSEmy_cursor;
這將關(guān)閉名為my_cursor的游標(biāo)。
遍歷游標(biāo):使用FOR循環(huán)可以遍歷游標(biāo)中的所有行。例如:
sql復(fù)制FORrowINmy_cursorLOOP
--處理行中的數(shù)據(jù)
ENDLOOP;
這將遍歷名為my_cursor的游標(biāo)中的所有行,并在每個(gè)循環(huán)迭代中處理行中的數(shù)據(jù)。
總之,Oracle游標(biāo)是Oracle數(shù)據(jù)庫(kù)中非常有用的對(duì)象,可以幫助用戶(hù)更快速地執(zhí)行SQL查詢(xún)并獲取查詢(xún)結(jié)果。熟練掌握游標(biāo)的使用可以提高數(shù)據(jù)庫(kù)操作的效率。
oracle對(duì)于多個(gè)大表關(guān)聯(lián)操作如何優(yōu)化速度
1、首先要建立適當(dāng)?shù)乃饕?。sql在索引字段不要加函數(shù),保證索引起效。如果是復(fù)合索引注意在sql的順序。如果已經(jīng)存在索引,建議你先重建索引先,因?yàn)榇髷?shù)據(jù)表的索引維護(hù)到了一個(gè)階段就是亂的,一般建議重建。建立好的一般可以獲得幾十倍的速度提升。
2、最大數(shù)據(jù)量的表放在最前,最小的表放在最后面。sql是從最后面開(kāi)始反向解析的。
3、其次是要把最有效縮小范圍的條件放到sql末尾去。尤其是主鍵或者索引字段的條件。
4、保證你sql的算法合理性。保證復(fù)雜度和空間度的合理性。
5、必要時(shí)候使用存儲(chǔ)過(guò)程。提升30%-40%的速度
6、建議你分頁(yè)讀取不要一下讀完所有的數(shù)據(jù)。(使用rownum),一下子數(shù)據(jù)太多會(huì)使得內(nèi)存不夠用的。如果這些都做了還不滿(mǎn)意的話,可以考慮建立幾個(gè)表空間,然后按照一個(gè)算法將各個(gè)表的數(shù)據(jù),平均的放在各個(gè)表空間內(nèi)(分表分區(qū)),在select的時(shí)候數(shù)據(jù)庫(kù)就會(huì)使用多線程到各個(gè)表空間索引數(shù)據(jù),這個(gè)一般不是上千萬(wàn)級(jí)的表是不用的。也不是所有人都會(huì)用。
my batis怎樣,實(shí)現(xiàn)mysql動(dòng)態(tài),分頁(yè)
在這些控件里要達(dá)到分頁(yè)的效果,一般都會(huì)傳2個(gè)參數(shù),第一個(gè)是表示當(dāng)前頁(yè)的索引(一般從0開(kāi)始),第二個(gè)表示當(dāng)前頁(yè)展示多少條業(yè)務(wù)記錄,然后將相應(yīng)的參數(shù)傳遞給List<T>getList(PagenateArgsargs)方法,最終實(shí)現(xiàn)數(shù)據(jù)庫(kù)中的分頁(yè)時(shí)候可以使用limit關(guān)鍵詞(針對(duì)mysql)進(jìn)行分頁(yè),如果是oracle或者sqlserver他們都有自帶的rownum函數(shù)可以使用。
針對(duì)上述思路,首先在demo.mybatis.model下面新建一個(gè)名為PagenateArgs的分頁(yè)參數(shù)實(shí)體類(lèi)與一個(gè)名為SortDirectionEnum的枚舉類(lèi),里面包含當(dāng)前頁(yè)面索引pageIndex,當(dāng)前頁(yè)展示業(yè)務(wù)記錄數(shù)pageSize,pageStart屬性表示從第幾條開(kāi)始,(pageStart=pageIndex*pageSize)因?yàn)閘imit關(guān)鍵詞用法是表示【limit起始條數(shù)(不包含),取幾條】,orderFieldStr排序字段,orderDirectionStr排序方向,所以具體創(chuàng)建如下:
packagedavid.mybatis.model;/**分頁(yè)參數(shù)實(shí)體類(lèi)*/publicclassPagenateArgs{privateintpageIndex;privateintpageSize;privateintpageStart;privateStringorderFieldStr;privateStringorderDirectionStr;publicPagenateArgs(){//TODOAuto-generatedconstructorstub}publicPagenateArgs(intpageIndex,intpageSize,StringorderFieldStr,StringorderDirectionStr){this.pageIndex=pageIndex;this.pageSize=pageSize;this.orderFieldStr=orderFieldStr;this.orderDirectionStr=orderDirectionStr;pageStart=pageIndex*pageSize;}publicintgetPageIndex(){returnpageIndex;}publicintgetPageStart(){returnpageStart;}publicintgetPageSize(){returnpageSize;}publicStringorderFieldStr(){returnorderFieldStr;}publicStringgetOrderDirectionStr(){returnorderDirectionStr;}}
packagedavid.mybatis.model;/**排序枚舉*/publicenumSortDirectionEnum{/**升序*/ASC,/**降序*/DESC}
完成上面的步驟以后在IVisitorOperation接口類(lèi)中繼續(xù)添加一個(gè)方法publicList<Visitor>getListByPagenate(PagenateArgsargs),這次的分頁(yè)其實(shí)也就是在這個(gè)的基礎(chǔ)上稍加改動(dòng)即可,IVisitorOperation接口類(lèi)改動(dòng)后如下所示:
packagedavid.mybatis.demo;importjava.util.List;importdavid.mybatis.model.PagenateArgs;importdavid.mybatis.model.Visitor;importdavid.mybatis.model.VisitorWithRn;publicinterfaceIVisitorOperation{/**基礎(chǔ)查詢(xún)*/publicVisitorbasicQuery(intid);/**添加訪問(wèn)者*/publicintadd(Visitorvisitor);/**刪除訪問(wèn)者*/publicintdelete(intid);/**更新訪問(wèn)者*/publicintupdate(Visitorvisitor);/**查詢(xún)?cè)L問(wèn)者*/publicVisitorquery(intid);/**查詢(xún)List*/publicList<Visitor>getList();/**分頁(yè)查詢(xún)List*/publicList<Visitor>getListByPagenate(PagenateArgsargs);}
接下來(lái)改動(dòng)VisitorMapper.xml配置文件了,新增一個(gè)<select>節(jié)點(diǎn)id與參數(shù)類(lèi)型參照前幾章的方式配置好,如下此處新增的id就為getListByPagenate,配置好以后如下
<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""
http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="david.mybatis.demo.IVisitorOperation"><!--useGeneratedKeys="true"代表是否使用自增長(zhǎng)序列,keyProperty="Id"指定自增長(zhǎng)列是哪一列,parameterType="Visitor"指定IVisitorOperation接口類(lèi)中定義中所傳的相應(yīng)類(lèi)型--><insertid="add"parameterType="Visitor"useGeneratedKeys="true"keyProperty="Id">insertintoVisitor(Name,Email,Status,CreateTime)values(#{name},#{email},#{status},#{createTime})</insert><deleteid="delete"parameterType="int">deletefromVisitorwherestatus>0andid=#{id}</delete><updateid="update"parameterType="Visitor">updateVisitorsetName=#{name},Email=#{email},Status=#{status}whereid=#{id}andStatus>0;</update><selectid="query"parameterType="int"resultType="Visitor">selectId,Name,Email,Status,CreateTimefromvisitorwhereid=#{id}andStatus>0orderbyId</select><selectid="basicQuery"parameterType="int"resultType="Visitor">select*fromvisitorwhereid=#{id}andStatus>0orderbyId</select><selectid="getList"resultMap="visitorRs"><includerefid="getListSql"/></select><sqlid="getListSql">select*fromVisitorwherestatus>0</sql><!--以下為新增部分用來(lái)分頁(yè),orderBySql這個(gè)提取出來(lái)是為了后面有示例復(fù)用--><resultMaptype="Visitor"id="visitorRs"><idcolumn="Id"property="id"/><resultcolumn="Name"property="name"/><resultcolumn="Email"property="email"/><resultcolumn="Status"property="status"/><resultcolumn="CreateTime"property="createTime"/></resultMap><selectid="getListByPagenate"parameterType="PagenateArgs"resultType="Visitor">select*from(<includerefid="getListSql"/><includerefid="orderBySql"/>)t<!--#{}表示參數(shù)化輸出,${}表示直接輸出不進(jìn)行任何轉(zhuǎn)義操作,自己進(jìn)行轉(zhuǎn)移--><iftest="pageStart>-1andpageSize>-1">limit#{pageStart},#{pageSize}</if></select><sqlid="orderBySql">orderby${orderFieldStr}${orderDirectionStr}</sql></mapper>這里面的字段屬性都是針對(duì)PagenateArgs參數(shù)類(lèi)中的屬性名,保持一致。
<iftest="pageStart>-1andpageSize>-1">limit#{pageStart},#{pageSize}</if>
在DemoRun類(lèi)中創(chuàng)建測(cè)試方法:
/**分頁(yè)參數(shù)*/publicstaticvoidqueryVisitorListWithPagenate(intpageIndex,intpageSize,StringorderField,StringorderDire){PagenateArgsargs=newPagenateArgs(pageIndex,pageSize,orderField,orderDire);SqlSessionsession=MybatisUtils.getSqlSession();IVisitorOperationvOperation=session.getMapper(IVisitorOperation.class);List<Visitor>visitors=vOperation.getListByPagenate(args);for(Visitorvisitor:visitors){System.out.println(visitor);}MybatisUtils.closeSession(session);MybatisUtils.showMessages(CRUD_Enum.List,visitors.size());}
DemoRun.queryVisitorListWithPagenate(0,100,"id",SortDirectionEnum.DESC.toString());
運(yùn)行后下測(cè)試結(jié)果,先按Id倒序排列,查的Visitor表一共有14條記錄,
假設(shè)取在第2頁(yè)取5條,執(zhí)行下面也就是6-10條數(shù)據(jù),這樣傳參數(shù)就行了
DemoRun.queryVisitorListWithPagenate(1,5,"id",SortDirectionEnum.DESC.toString());
結(jié)果如下:
實(shí)現(xiàn)了一個(gè)分頁(yè)邏輯.
請(qǐng)問(wèn)各位DBA大佬,SQL如何進(jìn)行多對(duì)多表的統(tǒng)計(jì)排序分頁(yè)查詢(xún)
以oracle為例:
SELECT*FROM
(
SELECTA.*,ROWNUMRN
FROM(SELECTrs.student_id,count(1)FROMrelationshiprsgroupbyrs.student_idorderbycount(1)desc)A
WHEREROWNUM<=10
)
WHERERN>=0
如何實(shí)現(xiàn)和調(diào)用oracle分頁(yè)存儲(chǔ)過(guò)程
1、首先建立一個(gè)包,用戶(hù)創(chuàng)建一個(gè)游標(biāo)類(lèi)型createorreplacepackagepkg_queryastypecur_queryisrefcursor;endpkg_query;2、創(chuàng)建存儲(chǔ)過(guò)程createORREPLACEPROCEDUREprc_query(p_tableNameinvarchar2,--表名p_strwhereinvarchar2,--查詢(xún)條件--*p_orderColumninvarchar2,--排序的列--*p_orderStyleinvarchar2,--排序方式--*p_curPageinoutNumber,--當(dāng)前頁(yè)p_pageSizeinoutNumber,--每頁(yè)顯示記錄條數(shù)p_totalRecordsoutNumber,--總記錄數(shù)--*p_totalPagesoutNumber,--總頁(yè)數(shù)v_curoutpkg_query。
如何使用使用分頁(yè)查詢(xún)來(lái)適應(yīng)挖掘海量數(shù)據(jù)呢
數(shù)據(jù)挖掘各類(lèi)算法中,常常需要遍歷整個(gè)數(shù)據(jù)庫(kù)(表)?,F(xiàn)實(shí)中的數(shù)據(jù)庫(kù)可能十分大,往往不可能通過(guò)一個(gè)簡(jiǎn)單的Select*的方式遍歷提取數(shù)據(jù)表內(nèi)的所有元組。直接用Select*的方式存在兩大問(wèn)題,一是Select*過(guò)后,可能要等很久數(shù)據(jù)庫(kù)才能將所有信息提交完畢,第二是得到的結(jié)果可能是很大,遠(yuǎn)遠(yuǎn)超過(guò)內(nèi)存的限制。
現(xiàn)在各種主流的數(shù)據(jù)庫(kù)都支持了分頁(yè)查詢(xún)的方式。
以O(shè)racle為例,通過(guò)rownum關(guān)鍵字可以獲取指定的行區(qū)間。
比如:
Select*fromXX。TABLE1whererownum=50;
以MySQL為例,提供了limit關(guān)鍵字,更加方便獲取中間某區(qū)間的行數(shù)據(jù)。
比如:Select*fromTABLE1limit50,100。MySQL的limit關(guān)鍵字用起來(lái)比Oracle要方便一些。不過(guò)各個(gè)數(shù)據(jù)庫(kù)的分頁(yè)查詢(xún)的速度我倒沒(méi)有研究過(guò),網(wǎng)上聽(tīng)一些高手們說(shuō),Oracle提供的分頁(yè)查詢(xún)效率要高一些。
Hibernate這樣的數(shù)據(jù)持久層提供的分頁(yè)查詢(xún),可以屏蔽掉各個(gè)不同的數(shù)據(jù)庫(kù)之間具體SQL實(shí)現(xiàn)差異。
Hiberante這樣的數(shù)據(jù)持久層工具一大好處就是可以屏蔽掉不同數(shù)據(jù)庫(kù)的之間的某些細(xì)節(jié)差異。
分頁(yè)查詢(xún)?cè)诓煌臄?shù)據(jù)庫(kù)上實(shí)現(xiàn)的SQL不一樣,所以要統(tǒng)一,最好使用Hibernate這樣的工具。
Queryq=session。createQuery("fromCatasc");
q。
setFirstResult(50);
q。setMaxResults(100);
Listl=q。list();
網(wǎng)上到處都可以搜尋到關(guān)于Hibernate內(nèi)部實(shí)現(xiàn)分頁(yè)查詢(xún)的解讀的文章。
可以看到,Hibernate內(nèi)部也是通過(guò)rownum,limit這些關(guān)鍵字來(lái)實(shí)現(xiàn)分頁(yè)的。
END,本文到此結(jié)束,如果可以幫助到大家,還望關(guān)注本站哦!
本文鏈接:http:///qianduan/3934.html