데이터 베이스 MySQL 튜토리얼 共享SQL区、私有SQL区与游标 (提到参数DB

共享SQL区、私有SQL区与游标 (提到参数DB

Jun 07, 2016 pm 03:48 PM
sql 공유됨 매개변수 말하는 커서 사적인

共享SQL区、私有SQL区与游标 一、共享SQL区 共享SQL区,就是Library cace中的游标对象的句柄和子堆这些数据的另一种叫法。 二、私有SQL区的概念 私有SQL区,在专用服务器模式下,存贮在PGA中。 (复习一下PGA概念: PGA在服务器端分配,记录各种不同的连接至

共享SQL区、私有SQL区与游标


一、共享SQL区
共享SQL区,就是Library cace中的游标对象的句柄和子堆这些数据的另一种叫法。
二、私有SQL区的概念
私有SQL区,在专用服务器模式下,存贮在PGA中。
(复习一下PGA概念:
PGA在服务器端分配,记录各种不同的连接至Oracle服务器的进程的信息,如登录时的用户名、密码等。每一个登录至Oracle的会话,都会在服务器端占用一块PGA。当会话刚登录时,每个用户的PGA大概占个几百KB左右的内存,并可在以后根据会话中的操作伸、缩。)
私有 SQL 区被分为两个区域,这两部分的生命周期有所不同:
·   持续数据区(persistentarea) 游标被关闭时被释放。
·   运行时区(run-timearea),当游标执行结束就会被释放。
1).
持续数据区(persistent area)
当打开一个游标时,持续区内存被创建。包含绑定信息(bind information)、SQL声明本身等之类的数据。此区只在游标关闭时才会被释放。
2).
运行时区
当游标在执行时被创建。当语句执行完毕或cancel之后被释放。
运行区或会话特定区是你的会话维护的相关游标的状态信息,例如:你的查询开始时的SCN、当前结果集的位置或其他特定于你的会话的东西。
另外,工作区(用于排序、哈希链接、Bitmap merge和Bitmap create等的内存区),也是运行时区的一部分。
如果我们在执行select name from mytable order byname;这条语句,Oracle做的事情大致上包括:  
三、 私有SQL区与共享SQL的关系
总结上面的内容可知,持续数据区中的信息,是在游标打开后,到游标被执行前,这一段期间所使用的内存。凡在此阶段中需被存进内存的信息,都是使用持续数据区的内存。因此,除了上面所提到的绑定信息、SQL声明本身之外,还有一类重要的信息,就是用来和共享SQL区某一SQL关联的地址信息。
为什么私有SQL区要和共享SQL区关联,因为执行计划在共享SQL中存储着。
下面一段话来自文档:
Oracle 为执行 SQL 语句的会话分配一个私有SQL 区。每个提交了 SQL 语句的会话都有一个私有 SQL 区。每个提交了相同 SQL 语句的用户都有自己的私有 SQL 区,但它们使用同一个共享 SQL 区(shared SQL area)。即多个私有 SQL 区可以和同一个共享 SQL 区相联系。
        这一段官样文章似乎清楚的描述了共享SQL区与私有SQL区的关系,但看过之后,估计还会让许多如我一样资质愚钝的人有雾里看花之感。看一看TOM大叔更清晰的比喻:
共享SQL就像是DLL,一个共享的库。
一条SQL就像是一个运行中的应用程序,它指向且使用共享库DLL。但每一个应用程序并不拷贝自己的私有二进制复本,它们只是共享它。
应用程序就是SQL,DLL共享库就是共享SQL
根据TOM的说法,执行计划这些相关SQL的信息,在共享池中只留一份,各个会话的UGA中的还是指针.
也就是说,在应用程序(SQL)中,应该存有相应DLL库(共享SQL)的指针,凭这个指针,将私有SQL区与共享SQL区联系起来。
这个指向共享SQL区的指针,和与之对应的SQL声明文本,是持续区最重要的内容。
有关多个私有SQL区共享一个共享SQL区的方式,在这一点应该就是借签了操作系统的动态链接库。
四、用户进程如何取得查询结果

Select * from table;
        我们发出如上声明后,查询结果如何返回给用户呢?
1.
先在Buffer cache定位块,如果Table的块Buffer cache中不存在,先从磁盘上读一部分块到Buffer cache。这就是物理读。这一过程,是需要PGA的协助。
当从磁盘上读块时,Oracle在每一次读时,尽量多读一些块到内存。但每次读的块数,受硬件、OS、Oracle的多块读参数和区大小等因素限制。
如果Table的块在Buffer cache中可以找到,就不再从磁盘读取了,这叫逻辑读。

2.
从Buffer cache中取出一条记录,立即交给用户。Oracle并不额外拷贝这条记录到任何位置。

3.
重复第2步,如果Buffer cache中当前块中符合用户条件的记录被读完,回到第1步。
        在上述这三步中,下一条要读取的记录的相关信息,就记录在运行时区,我们也可以称它为“结果集指针”。
        下面结合一个静态游标的例子来具体说明:
declare

cursor aa1 is select id from t1 where myid
mx number;
begin

open aa1; ------>静态游标在打开时就已经执行了查询

dbms_output.put_line('查询行数1:'||aa1%rowcount);---->但此时还没有开始读取,所以此Oracle并不知道

----查询将返回的行数,因此此处将显示0 。

for i in 1..10 loop

fetch aa1 into mx;
----用户程序要求读取记录,运行时区中指示要读取第一条记录。服务器进程负责在Buffer ----cache中查找相应块,如果相应块不在Buffer cache中,就从磁盘中读取相应的块到----Buffer cache中。然后从buffer cache取出第一行记录,立即将值传给用户进程。用户-------进程将得到的值传到指定变量中,此处即mx 。第一条记录读取完毕,此时,运行----时区中指示要读取的记录已经变为了第二条

dbms_output.put_line('查询结果:'||mx);


end loop;

dbms_output.put_line('查询行数2:'||aa1%rowcount);
----上面的循环一共抓取了10条记录,因此rowcount的

----值为10

close aa1;
end;
/
不管你的查询将返回多少行,在查询执行后、抓取记录时,抓取到哪条记录,才会去读相应的块。Oracle并不预先读取所有的块,构造一个结果集,然后从结果集中返回所查询的记录。这从两点可以得到证明,一是在游标打开后,Oracle并不能返回游标所查询的行数。如上例中的rowcount ,只有你抓取了N行,Oracle才知道,原来结果集中包括N行。你一行都不抓取,rowcount的值就是0 。
另外我们可以用一个例子来证明:
1. 发布如下声明,测试T4_1块的占用情况(下面很多视图将在Buffer cache一节中详述):
scott@MYTWO> select dbms_rowid.rowid_block_number(rowid)RID,min(rownum),max(rownum)  
from t4_1 group by dbms_rowid.rowid_block_number(rowid);

RID MIN(ROWNUM) MAX(ROWNUM)
---------- ----------- -----------

31508
1
38
-----> 1至38条记录占用块31508

31509
39
75
-----> 39至75条记录占用块31509

31510
76
112
-----> 等等

31511
113
150

31512
151
187

31513
188
225

31514
226
262
………………
2.
查看T4_1现有多少块在Buffer cache中
sys@MYTWO> select count(*) from x$bh where obj=7487;

COUNT(*)
----------

1
如果T4_1中有很多块在Buffer cache中,设法将它们释放。
(向某一表中大量插入或大量删除即可以达到目的,如:delete big_table whererownum    或按索引选择一个大表:select/*+index(表名)*/*from 表名 where 索引列 is not null;)
3.
在执行如下PL/SQL块:
declare

cursor aa1 is select id from t4_1;

mx number;
begin

open aa1;

for i in 1..75 loop

fetch aa1 into mx;

dbms_output.put_line('查询结果:'||mx);


end loop;

dbms_output.put_line('查询行数:'||aa1%rowcount);

close aa1;
end;
/
表T4_1共有2000行,64个块,Aa1游标将选择它的全部行。但程序只抓取75行,从步骤1的查询结果可知,也就是两个块。下面我们再次查询X$BH,看看Oracle到底读取了多少块到内存中:
4.
再次查询X$BH:
sys@MYTWO> select count(*) from x$bh where obj=7487;

COUNT(*)
----------

14
可以看到,T4_1共有64个块,但由于我们只抓取了一部分行,因此,只有一部分块被送进Buffer cache。这说明Oracle并不预先读所有块,而是“抓取到哪儿读到哪儿”。
但我们只抓取前75行,应该只读两个块才对,为什么会一下读14个块呢?这当然是由于多块读参数:db_file_multiblock_read_count,这就不属Library cache的内容了,本部分以Library cache为主,像多块读参数这些内容,以后再讨论。这里简单说一下。我这里设置此多块读参数为16,也就是说Oracle一次读盘,如果有可能,会一下读16个块到Buffercache。此参数以后再详细讨论,此处只所以没有读16个块,而是读14个块,很可能是区大小的原因。运行如下两个查询:
sys@MYTWO> select EXTENT_ID,FILE_ID,BLOCK_ID from dba_extents wheresegment_name='T4_1';

EXTENT_ID
FILE_ID
BLOCK_ID
---------- ---------- ----------

0
5
31505

1
5

31521

2
5
31537

3
5
31553
sys@MYTWO> select FILE#,dbablk,state from x$bh where obj=7487;

FILE#
DBABLK
STATE
---------- ---------- ----------

5
31507
1

5
31508
1

:
:
:

:
:
:

5
31520
1
已选择14行。
可以看到T4_1的0号区块编号从31505到31520,而Buffer cache中的块从31507到31520,整好读到一个区就停止了。
总结:Oracle并不将预先构造结果集、也不缓存结果。记录从buffer中直接读出传给用户进程。而游标则在抓取行时,记录下一个该抓取的行的信息。
Oracle并不缓存结果,我们可以从一个例看出,执行下列声明:
scott@MYTWO> set autotrace traceonly;
scott@MYTWO> select * from aa_1;
未选定行
Execution Plan
----------------------------------------------------------

0
SELECT STATEMENT Optimizer=CHOOSE

1
0
TABLE ACCESS (FULL) OF 'AA_1'
Statistics
----------------------------------------------------------

0
recursive calls

0
db block gets

3
consistent gets

0
physical reads

0
redo size

215
bytes sent via SQL*Net to client

372
bytes received via SQL*Net from client

1
SQL*Net roundtrips to/from client

0
sorts (memory)

0
sorts (disk)

0
rows processed
你可以重复执行select * from aa_1几次,所得资料应该是一样的。
从上面的资料中可以看出,有3次逻辑读。这说明Oracle在Buffercache读了三次。这三个逻辑读,其实读的都是段头。这是Oracle重新开始一个查询的标志,说明Oracle正准备重新开始抓取行,这说明Oracle并没有缓存结果集。如果Oracle缓存有结果集的话,根本不必再到Buffer cache中读取这些头部信息块,直接根据结果集返回结果即可。
五、游标
        是为游标下一个准确定义的时候了。
来源自文档:A cursor is a handle or name fora private SQL area.
即:游标是私有SQL区的句柄(或名字)。
游标可以说是所有私有SQL区中各种信息的总称,它并不实际存在,它只是由所有私有SQL区中的部件组成的。游标可以说是私有SQL区的代名词。
我们可以这样说:用户进程通过游标执行自己的SQL声明,仍然后将存储在服务器中的信息取出呈现给用户。
六、有关游标的视图
每一个游标(即私有SQL区),在Library cache中都有一个对象与之对应。并且,这个对象的句柄是加了模式为1的锁的。  
V$open_cursor 视图是Oracle提供的用来查看当前所有游标的视图。观察它和X$KGLLK的对应关系,可对游标与Library cache的联系,有一定的了解。
例10:观察V$open_cursor与X$KGLLK的对应关系:
v$fixed_view_definition视图中有Oracle中所有动态性能视图(V$视图)的定义,如下查询,可知V$OPEN_CURSOR的由来。
select view_definition from v$fixed_view_definition whereview_name='V$OPEN_CURSOR';
再进一步查询,即可看到V$OPEN_CURSOR与X$KGLLK的联系。
通过V$OPEN_CURSOR与X$KGLLK的关系,可知对Oracle来说,一个打开的游标,必将有一个加了LOCK为1的锁的句柄与之对应。
除了V$open_cursor,Oracle中并没提供专门的显示游标信息的视图。因为游标中很多信息都存储在PGA中。而Oracle中的V$系列动态性能视图,都是来自SGA,或控制文件。PGA中的信息,只有用户会话的服务进程才能访问,因为它不是共享内存,因此,无法像X$视图那样由后台进程统一管理。
而V$open_cursor虽然是针对游标的,但它是利用PGA中私有SQL区和SGA中共享SQL区的联系,显示的还是SGA中的信息。

 

 

 

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Apr 17, 2024 pm 02:57 PM

HQL과 SQL은 Hibernate 프레임워크에서 비교됩니다. HQL(1. 객체 지향 구문, 2. 데이터베이스 독립적 쿼리, 3. 유형 안전성), SQL은 데이터베이스를 직접 운영합니다(1. 데이터베이스 독립적 표준, 2. 복잡한 실행 파일) 쿼리 및 데이터 조작).

WeChat Enterprise에서 화면을 공유하는 방법 WeChat Enterprise에서 화면을 공유하는 방법 Feb 28, 2024 pm 12:43 PM

점점 더 많은 기업이 독점 기업 WeChat을 선택하고 있습니다. 이는 기업과 고객, 파트너 간의 의사소통을 촉진할 뿐만 아니라 업무 효율성도 크게 향상시킵니다. Enterprise WeChat에는 풍부한 기능이 있으며 그 중 화면 공유 기능이 매우 인기가 있습니다. 회의 중에 화면을 공유함으로써 참가자들은 콘텐츠를 보다 직관적으로 표시하고 보다 효율적으로 협업할 수 있습니다. 그렇다면 WeChat Enterprise에서 화면을 효율적으로 공유하는 방법은 무엇입니까? 아직 모르는 사용자를 위해 이 튜토리얼 가이드가 도움이 되기를 바랍니다. WeChat Enterprise에서 화면을 공유하는 방법은 무엇입니까? 1. Enterprise WeChat 메인 인터페이스 왼쪽의 파란색 영역에 "컨퍼런스" 아이콘이 표시됩니다. 클릭하면 세 가지 컨퍼런스 모드가 나타납니다.

친구들과 wallpaperengine을 공유하는 방법 친구들과 wallpaperengine을 공유하는 방법 Mar 18, 2024 pm 10:00 PM

사용자는 WallpaperEngine을 사용할 때 얻은 배경화면을 친구들과 공유할 수 있습니다. 많은 사용자는 자신이 좋아하는 배경화면을 로컬에 저장한 다음 소셜 소프트웨어를 통해 친구들과 공유할 수 있습니다. wallpaperengine을 친구들과 공유하는 방법 답변: 로컬에 저장하고 친구들과 공유하세요. 1. 좋아하는 배경화면을 로컬에 저장한 다음 소셜 소프트웨어를 통해 친구들과 공유하는 것이 좋습니다. 2. 폴더를 통해 컴퓨터에 업로드한 후 컴퓨터의 창작 워크숍 기능을 사용하여 공유를 클릭할 수도 있습니다. 3. 컴퓨터에서 Wallpaperengine을 사용하고 크리에이티브 워크숍의 옵션 막대를 열고

Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Mar 11, 2024 pm 12:09 PM

Oracle과 DB2는 일반적으로 사용되는 관계형 데이터베이스 관리 시스템으로, 각각 고유한 SQL 구문과 특성을 가지고 있습니다. 이 기사에서는 Oracle과 DB2의 SQL 구문을 비교 및 ​​차이점을 설명하고 구체적인 코드 예제를 제공합니다. 데이터베이스 연결 Oracle에서는 다음 문을 사용하여 데이터베이스에 연결합니다. CONNECTusername/password@database DB2에서 데이터베이스에 연결하는 문은 다음과 같습니다. CONNECTTOdataba

Oracle SQL의 나누기 연산 사용법 Oracle SQL의 나누기 연산 사용법 Mar 10, 2024 pm 03:06 PM

"OracleSQL의 나눗셈 연산 사용법" OracleSQL에서 나눗셈 연산은 일반적인 수학 연산 중 하나입니다. 데이터 쿼리 및 처리 중에 나누기 작업은 필드 간의 비율을 계산하거나 특정 값 간의 논리적 관계를 도출하는 데 도움이 될 수 있습니다. 이 문서에서는 OracleSQL의 나누기 작업 사용법을 소개하고 구체적인 코드 예제를 제공합니다. 1. OracleSQL의 두 가지 분할 연산 방식 OracleSQL에서는 두 가지 방식으로 분할 연산을 수행할 수 있습니다.

MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 Feb 26, 2024 pm 07:48 PM

MyBatis 동적 SQL 태그 해석: Set 태그 사용법에 대한 자세한 설명 MyBatis는 풍부한 동적 SQL 태그를 제공하고 데이터베이스 작업 명령문을 유연하게 구성할 수 있는 탁월한 지속성 계층 프레임워크입니다. 그 중 Set 태그는 업데이트 작업에서 매우 일반적으로 사용되는 UPDATE 문에서 SET 절을 생성하는 데 사용됩니다. 이 기사에서는 MyBatis에서 Set 태그의 사용법을 자세히 설명하고 특정 코드 예제를 통해 해당 기능을 보여줍니다. Set 태그란 무엇입니까? Set 태그는 MyBati에서 사용됩니다.

Windows 11 폴더 공유 가이드: 파일과 데이터를 쉽게 공유 Windows 11 폴더 공유 가이드: 파일과 데이터를 쉽게 공유 Mar 13, 2024 am 11:49 AM

일상 생활과 직장에서 우리는 종종 서로 다른 장치 간에 파일과 폴더를 공유해야 합니다. Windows 11 시스템에는 편리한 폴더 공유 기능이 내장되어 있어 개인 파일의 개인 정보를 보호하면서 동일한 네트워크 내에서 다른 사람들과 필요한 콘텐츠를 쉽고 안전하게 공유할 수 있습니다. 이 기능을 사용하면 개인 정보 유출에 대한 걱정 없이 파일을 간단하고 효율적으로 공유할 수 있습니다. Windows 11 시스템의 폴더 공유 기능을 통해 우리는 보다 편리하게 협력하고, 소통하고 협업할 수 있어 업무 효율성과 생활 편의성이 향상됩니다. 공유 폴더를 성공적으로 구성하려면 먼저 다음 조건을 충족해야 합니다. 공유에 참여하는 모든 장치가 동일한 네트워크에 연결되어 있습니다. 네트워크 검색을 활성화하고 공유를 구성합니다. 대상 장치를 알아라

C++ 함수 매개변수 유형 안전성 확인 C++ 함수 매개변수 유형 안전성 확인 Apr 19, 2024 pm 12:00 PM

C++ 매개변수 유형 안전성 검사는 함수가 컴파일 시간 검사, 런타임 검사 및 정적 어설션을 통해 예상된 유형의 값만 허용하도록 보장하여 예기치 않은 동작 및 프로그램 충돌을 방지합니다. 컴파일 시간 유형 검사: 컴파일러가 유형 호환성을 검사합니다. 런타임 유형 검사: 동적_캐스트를 사용하여 유형 호환성을 확인하고 일치하는 항목이 없으면 예외를 발생시킵니다. 정적 어설션: 컴파일 타임에 유형 조건을 어설션합니다.

See all articles