当前位置:文档之家› oracle-SQL语句执行原理和完整过程详解

oracle-SQL语句执行原理和完整过程详解

oracle-SQL语句执行原理和完整过程详解
oracle-SQL语句执行原理和完整过程详解

SQL语句执行过程详解

一条sql,plsql的执行到底是怎样执行的呢?

一、SQL语句执行原理:

第一步:客户端把语句发给服务器端执行

当我们在客户端执行select 语句时,客户端会把这条SQL 语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作,他的主要任务就是把客户端产生的一些SQL 语句发送给服务器端。虽然在客户端也有一个数据库进程,但是,这个进程的作用跟服务器上的进程作用事不相同的。服务器上的数据库进程才会对SQL 语句进行相关的处理。不过,有个问题需要说明,就是客户端的进程跟服务器的进程是一一对应的。也就是说,在客户端连接上服务器后,在客户端与服务器端都会形成一个进程,客户端上的我们叫做客户端进程;而服务器上的我们叫做服务器进程。

第二步:语句解析

当客户端把SQL 语句传送到服务器后,服务器进程会对该语句进行解析。同理,这个解析的工作,

其会做很多小动作。

也是在服务器端所进行的。虽然这只是一个解析的动作,但是,“”

1. 查询高速缓存(library cache)。服务器进程在接到客户端传送过来的SQL 语句时,不

会直接去数据库查询。而是会先在数据库的高速缓存中去查找,是否存在相同语句的执行计划。如果在数据高速缓存中,则服务器进程就会直接执行这个SQL 语句,省去后续的工作。所以,采用高速数据缓存的话,可以提高SQL 语句的查询效率。一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高,另一方面,也是因为这个语句解析的原因。

不过这里要注意一点,这个数据缓存跟有些客户端软件的数据缓存是两码事。有些客户端软件为了提高查询效率,会在应用软件的客户端设置数据缓存。由于这些数据缓存的存在,可以提高客户端应用软件的查询效率。但是,若其他人在服务器进行了相关的修改,由于应用软件数据缓存的存在,导致修改的数据不能及时反映到客户端上。从这也可以看出,应用软件的数据缓存跟数据库服务器的高速数据缓存不是一码事。

2. 语句合法性检查(data dict cache)。当在高速缓存中找不到对应的SQL 语句时,则服

务器进程就会开始检查这条语句的合法性。这里主要是对SQL 语句的语法进行检查,看看其是否合乎语法规则。如果服务器进程认为这条SQL 语句不符合语法规则的时候,就会把这个错误信息,反馈给客户端。在这个语法检查的过程中,不会对SQL 语句中所包含的表名、列名等等进行SQL 他只是语法上的检查。

3. 语言含义检查(data dict cache)。若SQL 语句符合语法上的定义的话,则服务器进程

接下去会对语句中的字段、表等内容进行检查。看看这些字段、表是否在数据库中。如果表名与列名不准确的话,则数据库会就会反馈错误信息给客户端。所以,有时候我们写select 语句的时候,若语法与表名或者列名同时写错的话,则系统是先提示说语法错误,等到语法完全正确后,再提示说列名或表名错误。

4. 获得对象解析锁(control structer)。当语法、语义都正确后,系统就会对我们需要查询的对象加锁。这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象的结构发生改变。

5. 数据访问权限的核对(data dict cache)。当语法、语义通过检查之后,客户端还不一定

能够取得数据。服务器进程还会检查,你所连接的用户是否有这个数据访问的权限。若你连接上服务器

的用户不具有数据访问权限的话,则客户端就不能够取得这些数据。有时候我们查询数据的时候,辛辛苦

最后系统返回个没有权限访问数据的错误信息,让我们气苦地把SQL 语句写好、编译通过,但是, “”

半死。这在前端应用软件开发调试的过程中,可能会碰到。所以,要注意这个问题,数据库服务器进程先检查语法与语义,然后才会检查访问权限。

6. 确定最佳执行计划?。当语句与语法都没有问题,权限也匹配的话,服务器进程还是不会直接对数据库文件进行查询。服务器进程会根据一定的规则,对这条语句进行优化。不过要注意,这个优化是有限的。一般在应用软件开发的过程中,需要对数据库的sql 语言进行优化,这个优化的作用要大大地大于服务器进程的自我优化。所以,一般在应用软件开发的时候,数据库的优化是少不了的。当服务器进程的优化器确定这条查询语句的最佳执行计划后,就会将这条SQL 语句与执行计划保存到数据高速缓存(library cache)。如此的话,等以后还有这个查询时,就会省略以上的语法、语义与权限检查的步骤,而直接执行SQL 语句,提高SQL 语句处理效率。

第三步:语句执行

语句解析只是对SQL 语句的语法进行解析,以确保服务器能够知道这条语句到底表达的是什么意思。等到语句解析完成之后,数据库服务器进程才会真正的执行这条SQL 语句。这个语句执行也分两

种情况。

一是若被选择行所在的数据块已经被读取到数据缓冲区的话,则服务器进程会直接把这个数据传递

给客户端,而不是从数据库文件中去查询数据。

若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲区中(buffer cache)。

第四步:提取数据

当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给

用户端进程,从而完成整个查询动作。从这整个查询处理过程中,我们在数据库开发或者应用软件开发过程中,需要注意以下几点:

一是要了解数据库缓存跟应用软件缓存是两码事情。数据库缓存只有在数据库服务器端才存在,在

客户端是不存在的。只有如此,才能够保证数据库缓存中的内容跟数据库文件的内容一致。才能够根据

相关的规则,防止数据脏读、错读的发生。而应用软件所涉及的数据缓存,由于跟数据库缓存不是一码事情,所以,应用软件的数据缓存虽然可以提高数据的查询效率,但是,却打破了数据一致性的要求,有时候会发生脏读、错读等情况的发生。所以,有时候,在应用软件上有专门一个功能,用来在必要的时候清除数据缓存。不过,这个数据缓存的清除,也只是清除本机上的数据缓存,或者说,只是清除这个应用程序

的数据缓存,而不会清除数据库的数据缓存。

二是绝大部分SQL 语句都是按照这个处理过程处理的。我们DBA 或者基于Oracle 数据库的开发人员了解这些语句的处理过程,对于我们进行涉及到SQL 语句的开发与调试,是非常有帮助的。有时候,掌握这些处理原则,可以减少我们排错的时间。特别要注意,数据库是把数据查询权限的审查放在语法语义的后面进行检查的。所以,有时会若光用数据库的权限控制原则,可能还不能满足应用软件权限控制的需要。此时,就需要应用软件的前台设置,实现权限管理的要求。而且,有时应用数据库的权限管理,也有点显得繁琐,会增加服务器处理的工作量。因此,对于记录、字段等的查询权限控制,大部分程

序涉及人员喜欢在应用程序中实现,而不是在数据库上实现。

DBCC DROPCLEANBUFFERS

从缓冲池中删除所有清除缓冲区。

DBCC FREEPROCCACHE

从过程缓存中删除所有元素。

DBCC FREESYSTEMCACHE

从所有缓存中释放所有未使用的缓存条目

SQL语句中的函数、关键字、排序等执行顺序:

1. FROM 子句返回初始结果集。

2. WHERE 子句排除不满足搜索条件的行。

3. GROUP BY 子句将选定的行收集到GROUP BY 子句中各个唯一值的组中。

4. 选择列表中指定的聚合函数可以计算各组的汇总值。

5. 此外,HAVING 子句排除不满足搜索条件的行。

6. 计算所有的表达式;

7. 使用order by 对结果集进行排序。

8. 查找你要搜索的字段。

二、SQL语句执行完整过程:

1.用户进程提交一个sql 语句: update temp set a=a*2,给服务器进程。

2.服务器进程从用户进程把信息接收到后,在PGA 中就要此进程分配所需内存,存储相关的信息,如在会话内存存储相关的登录信息等。

3.服务器进程把这个sql 语句的字符转化为ASCII 等效数字码,接着这个ASCII 码被传递给一个HASH 函数,并返回一个hash 值,然后服务器进程将到shared pool 中的library cache 中去查找是否存在相同的hash 值,如果存在,服务器进程将使用这条语句已高速缓存在SHARED POOL 的library cache 中的已分析过的版本来执行。

4.如果不存在,服务器进程将在CGA 中,配合UGA 内容对sql,进行语法分析,首先检查语法的正确性,接着对语句中涉及的表,索引,视图等对象进行解析,并对照数据字典检查这些对象的名称以及相关结构,并根据ORACLE 选用的优化模式以及数据字典中是否存在相应对象的统计数据和是否使用了存储大纲来生成一个执行计划或从存储大纲中选用一个执行计划,然后再用数据字典核对此用户对相应对象的执行权限,最后生成一个编译代码。

5.ORACLE 将这条sql 语句的本身实际文本、HASH 值、编译代码、与此语名相关联的任何统计数据和该语句的执行计划缓存在SHARED POOL 的library cache中。服务器进程通过SHARED POOL 锁存器(shared pool latch)来申请可以向哪些共享PL/SQL 区中缓存这此内容,也就是说被SHARED POOL 锁存器锁定的PL/SQL 区中的块不可被覆盖,因为这些块可能被其它进程所使用。

6.在SQL 分析阶段将用到LIBRARY CACHE,从数据字典中核对表、视图等结构的时候,需要将数据字典从磁盘读入LIBRARY CACHE,因此,在读入之前也要使用LIBRARY CACHE 锁存器(library cache pin,library cache lock)来申请用于缓存数据字典。到现在为止,这个sql 语句已经被编译成可执行的代码了,但还不知道要操作哪些数据,所以服务器进程还要为这个sql 准备预处理数据。

7.首先服务器进程要判断所需数据是否在db buffer 存在,如果存在且可用,则直接获取该数据,同时根据LRU 算法增加其访问计数;如果buffer 不存在所需数据,则要从数据文件上读取首先服务器进程将在表头部请求TM 锁(保证此事务执行过程其他用户不能修改表的结构),如果成功加TM 锁,再请求一些行级锁(TX 锁),如果TM、TX 锁都成功加锁,那么才开始从数据文件读数据,在读数据之前,要先为读取的文件准备好buffer 空间。服务器进程需要扫面LRU list 寻找free db buffer,扫描的过程中,服务器进程会把发现的所有已经被修改过的db buffer 注册到dirty list 中, 这些dirty buffer 会通过dbwr 的触发条件,随后会被写出到数据文件,找到了足够的空闲buffer,就可以把请求的数据行所在的数据块放入到db buffer 的空闲区域或者覆盖已经被挤出LRU list 的非脏数据块缓冲区,并排列在LRU list 的头部,也就是在数据块放入DB BUFFER 之前也是要先申请db buffer 中的锁存器,成功加锁后,才能读数据到db buffer。

8.记日志现在数据已经被读入到db buffer 了,现在服务器进程将该语句所影响的并被读

入db buffer 中的这些行数据的rowid 及要更新的原值和新值及scn 等信息从PGA 逐条的写入redo log buffer 中。在写入redo log buffer 之前也要事先请求redo log buffer 的锁存器,成功加锁后才开始写入,当写入达到redo log buffer 大小的三分之一或写入量达到1M 或超过三秒后或发生检查点时或者dbwr 之前发生,都会触发lgwr 进程把redo log buffer 的数据写入磁盘上的redo file 文件中(这个时候会产生log file sync 等待事件)

已经被写入redofile 的redo log buffer 所持有的锁存器会被释放,并可被后来的写入信息覆盖,

redo log buffer是循环使用的。Redo file 也是循环使用的,当一个redo file 写满后,lgwr 进程会自动切换到下一redo file(这个时候可能出现log fileswitch(checkpoint complete)等待事件)。如果是归档模式,归档进

程还要将前一个写满的redo file 文件的内容写到归档日志文件中(这个时候可能出现log file

switch(archiving needed)。

9.为事务建立回滚段在完成本事务所有相关的redo log buffer 之后,服务器进程开始改写这个db buffer 的块头部事务列表并写入scn,然后copy 包含这个块的头部事务列表及scn 信息的数据副本放入回滚段中,将

这个前映“

像用于以后的回滚、恢复和一致性读。(回滚段可以中的信息称为数据块的前映像,”

这时回滚段““

存储在专门的回滚表空间中,这个表空间由一个或多个物理文件组成,并专用于回滚表空间,回滚段也可在其它表空间中的数据文件中开辟。

10.本事务修改数据块准备工作都已经做好了,现在可以改写db buffer 块的数据内容了,并在块的头部写入回滚段的地址。

11.放入dirty list 如果一个行数据多次update 而未commit,“

映像,除了第

则在回滚段中将会有多个前“

信息和前前映像回滚段地址。一个

其他每个前映像的头部都有scn “”

一个前映像含有scn 信息外,““

”“

update 只对应一个scn,然后服务器进程将在dirty list 中建立一

条指向此db buffer 块的指针(方便dbwr 进程可以找到dirty list 的db buffer 数据块并写入数据文件中)。接着服务器进程会从数据文件中继续读入第二个数据块,重复前一数据块的动作,数据块的读入、记日志、建立回滚段、修改数据块、放入dirty list。当dirty queue 的长度达到阀值(一般是25%),服务器进程将通知dbwr 把脏数据写出,就是释放db buffer 上的锁存器,腾出更多的free db buffer。前面一直都是在说明oracle 一次读一个数据块,其实oracle 可以一次读入多个数据块(db_file_multiblock_read_count 来设置一次读入块的个数)

说明: 在预处理的数据已经缓存在db buffer 或刚刚被从数据文件读入到db buffer 中,就要根据sql 语句的类型来决定接下来如何操作。

1>如果是select 语句,则要查看db buffer 块的头部是否有事务,如果有事务,则从回滚段中读取数据;如果没有事务,则比较select 的scn 和db buffer 块头部的scn,如果前者小于后者,仍然要从回滚段中读取数据;如果前者大于后者,说明这是一非脏缓存,可以直接读取这个db buffer 块的中内容。

2>如果是DML 操作,则即使在db buffer 中找到一个没有事务,而且SCN 比自己小的非脏

缓存数据块,服务器进程仍然要到表的头部对这条记录申请加锁,加锁成功才能进行后续动作,如果不成功,则要等待前面的进程解锁后才能进行动作(这个时候阻塞是tx 锁阻塞)。

用户commit 或rollback 到现在为止,数据已经在db buffer 或数据文件中修改完

成,但是否要永久写到数文件中,要由用户来决定commit(保存更改到数据文件) rollback 撤销数据的更改)。

1.用户执行commit 命令

只有当sql 语句所影响的所有行所在的最后一个块被读入db buffer 并且重做信息被写入redo log buffer(仅指日志缓冲区,而不包括日志文件)之后,用户才可以发去commit 命令,commit 触发lgwr 进程,但不强制立即dbwr来释放所有相应db buffer 块的锁(也就是no-force-at-commit,即提交不强制写),也就是说有可能虽然已经commit 了,但在随后的一段时间内dbwr 还在写这条sql 语句所涉及的数据块。表头部的行锁并不在commit 之后立即释放,而是要等dbwr 进程完成之后才释放,这就可能会出现一个用户请求另一用户已经commit 的资源不成功的现象。

A .从Commit 和dbwr 进程结束之间的时间很短,如果恰巧在commit 之后,dbwr 未结束之前断电,因为commit 之后的数据已经属于数据文件的内容,但这部分文件没有完全写入到数据文件中。所以需要前滚。由于commit 已经触发lgwr,这些所有未来得及写入数据文件的更改会在实例重启后,由smon 进程根据重做日志文件来前滚,完成之前commit 未完成的工作(即把更改写入数据文件)。

B.如果未commit 就断电了,因为数据已经在db buffer 更改了,没有commit,说明这部分数据不属于数据文件,由于dbwr 之前触发lgwr 也就是只要数据更改,(肯定要先有log) 所有DBWR,在数据文件上的修改都会被先一步记入重做日志文件,实例重启后,SMON 进程再根据重做日志文件来回滚。

其实smon 的前滚回滚是根据检查点来完成的,当一个全部检查点发生的时候,首先让LGWR 进程将redo log buffer 中的所有缓冲(包含未提交的重做信息)写入重做日志文件,然后让dbwr 进程将db buffer 已提交的缓冲写入数据文件(不强制写未提交的)。然后更新控制文件和数据文件头部的SCN,表明当前数据库是一致的,在相邻的两个检查点之间有很多事务,有提交和未提交的。

像前面的前滚回滚比较完整的说法是如下的说明:

A.发生检查点之前断电,并且当时有一个未提交的改变正在进行,实例重启之后,SMON 进程将从上一个检查点开始核对这个检查点之后记录在重做日志文件中已提交的和未提交改变,因为

dbwr 之前会触发lgwr,所以dbwr 对数据文件的修改一定会被先记录在重做日志文件中。因此,断电前被DBWN 写进数据文件的改变将通过重做日志文件中的记录进行还原,叫做回滚,

B. 如果断电时有一个已提交,但dbwr 动作还没有完全完成的改变存在,因为已经提交,提交会触发lgwr 进程,所以不管dbwr 动作是否已完成,该语句将要影响的行及其产生的结果一定已经记录在重做日志文件中了,则实例重启后,SMON 进程根据重做日志文件进行前滚.

实例失败后用于恢复的时间由两个检查点之间的间隔大小来决定,可以通个四个参数设置检查点执行的频率:

Log_checkpoint_interval: 决定两个检查点之间写入重做日志文件的系统物理块(redo blocks)

的大小,默认值是0,无限制。

log_checkpoint_timeout: 两个检查点之间的时间长度(秒)默认值1800s。

fast_start_io_target: 决定了用于恢复时需要处理的块的多少,默认值是0,无限制。

fast_start_mttr_target: 直接决定了用于恢复的时间的长短,默认值是0,无限制(SMON 进程执行的前滚和回滚与用户的回滚是不同的,SMON 是根据重做日志文件进行前滚或回滚,而用户的回滚一定是根据回滚段的内容进行回滚的。

在这里要说一下回滚段存储的数据,假如是delete 操作,则回滚段将会记录整个行的数据,假如是update,则回滚段只记录被修改了的字段的变化前的数据(前映像),也就是没有被修改的字段是不会被记录的,假如是insert,则回滚段只记录插入记录的rowid。这样假如事务提交,那回滚段中简单标记该事务已经提交;假如是回退,则如果操作是delete,回退的时候把回滚段中数据重新写回数据块,操作如果是update,则把变化前数据修改回去,操作如果是insert,则根据记录的rowid 把该记录删除。

2.如果用户rollback。

则服务器进程会根据数据文件块和DB BUFFER 中块的头部的事务列表和SCN 以及回滚段地址找到回滚段中相应的修改前的副本,并且用这些原值来还原当前数据文件中已修改但未提交的改变。如果有多个

像的头部找到前前映像的回滚段地址,一直找到同一事务下的最早的服务器进程会在一个前映”“”

“”

前映像,“

一个前映像为止。一旦发出了COMMIT,用户就不能rollback,这使得COMMIT 后DBWR 进程还没有“”

全部完成的后续动作得到了保障。到现在为例一个事务已经结束了。

说明: TM 锁: 符合lock 机制的,用于保护对象的定义不被修改。TX 锁: 这个锁代表一个事务,是行

级锁,用数据块头、数据记录头的一些字段表示,也是符合lock 机制,有resource structure、lock structure、enqueue 算法。

mysql分享(1)-sql语句执行的11个步骤

IREDPURE mysql执行查询语句的11个步骤(分享1) ZERO 2016/02/19

每个人都会犯错误,有的人把犯过的错误记录下来,进一步总结,形成了自己的一套理论;有的人,则在同一个错误上一错再错,不停的抱怨,然后 再犯错,然后再抱怨,产生了一个死循环…… 1、项目结束后的思考 每个项目的结束,每个人都会有自己的收获,不同水平的人总结出来的东西可能不一样!但是对自己而言,都是进步,都是让自己在原有的基础上强大 了一点点。我们在每个项目结束后,都应该对自己做一个总结,这是我们强大的来源,日记月累,必定是一笔不小的财富! 2、mysql查询语句执行的11个步骤 (8) select (9) distinct (1) from (1) (3) join (1) (2) on (4) where (5) group by (6) with {cube | rollup} (7) having (10) order by (11) limit 以上是这个11个步骤,这是《mysql技术内幕之sql编程》这本书上面得出的结论,有兴趣的同学也可以去看下,很不错的一本书! ps: Paul DuBois( 杜波依斯) Sun 公司MySQL文档团队的技术作者、开源社区和MySQL社区活跃的技术专家,同时也是一名数据库管理员。他曾参 与过MySQL在线文档的编写工作 接下来我们举一个例子,分别解释sql语句的执行流程! 3、举例说明sql语句的执行流程 【1】进行准备工作 CREATE TABLE `Customer` ( `CustomerID` varchar(10) NOT NULL, `CityName` varchar(10) NOT NULL, PRIMARY KEY (`CustomerID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; LOCK TABLES `Customer` WRITE; INSERT INTO `Customer` VALUES ('163','hangzhou'),('9you','shanghai'),('tx','hangzhou'), ('baidu','hangzhou'); UNLOCK TABLES; ================================================================================================================= CREATE TABLE `Orders` ( `OrdersID` int(11) NOT NULL AUTO_INCREMENT, `CustomerID` varchar(10) DEFAULT NULL, PRIMARY KEY (`OrdersID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; LOCK TABLES `Orders` WRITE; INSERT INTO `Orders` VALUES (1,'163'),(2,'163'),(3,'9you'),(4,'9you'),(5,'9you'),(6,'tx'),(7,null); UNLOCK TABLES; =====================================================================================================最终结果如下: 通过如下语句查询来杭州,且订单小于2的用户,并且查询出来他们的订单数量,查询的结果按照订单数从大到小排列: select Customer.CustomerID, Customer.CityName, count(Orders.CustomerID) as OrdersNumber from Customer left join Orders on Customer.CustomerID = Orders.CustomerID where Customer.CityName='HangZhou' group by Customer.CustomerID having count(Orders.CustomerID) < 2 order by OrdersNumber desc; ps:在得出正确的语句之前,我写了两次错误的sql,个人认为还是很有借鉴意义的:

JAVA基础第6章异常处理机制_练习题

第6章异常处理机制 一、选择题 1.下列关于异常的说法正确的是(B)。 A.异常是编译时的错误 B.异常是运行时出现的错误 C.异常就是程序错误,程序错误就是异常 D.以上都不对 2.下列哪个类是异常类的父类(根类)(A)。 A.Exception B.ArithmeticException C.NullPointerException D.ArrayIndexOutofBoundException 3.有关下列异常处理机制叙述正确的是(C)。 try{ 可能产生异常的语句块; }catch(exceptiontype1 e){ 处理异常e的语句块; }catch(exceptiontype2 e){ 处理异常e的语句块; } …… finally{ 最终处理语句块; } A.try子句可能有多个,catch子句可能有多个,finally子句必须有。 B.多个catch参数中的异常类可以有父子关系,但父类异常的catch子句应该在子类异常的catch子句前面。 C.如果try子句没有抛出任何异常,则跳过catch子句,转移到finally子句继续执行。 D.当try子句监视的语句块抛出异常时,运行时系统会根据catch子句的顺序,从第一个开始,逐个查找能够捕获该异常的catch子句并执行catch子句内的语句块以完成对异常的处理,然后继续执行后面的catch子句,最后转移到finally子句,执行该子句中的语句块。4.有关throw和throws的说法中不正确的是(C)。 A.throw的作用是抛出异常,后面加的是异常类的对象。 B.throws的作用是向外抛出异常即声明要产生的若干异常,后面加的是异常类的类名。 C.throws只能声明要产生的自定义异常,也就是后面只能加自定义异常类。 D.以上都不对。 5.下列程序运行结果是(C)。 public class E { public static void main(String argv[]){ E m = new E(); System.out.println(m.amethod()); } public int amethod(){

SQL语句执行效率及分析

SQL语句执行效率及分析 2. SQL提高查询效率 2008-05-12 21:20 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用 索引而进行全表扫描,如: select id from t where num=10 or num=20 可以这样查询: select id from t where num=10 union all select id from t where num=20 5.in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 6.下面的查询也将导致全表扫描: select id from t where name like '%abc%' 若要提高效率,可以考虑全文检索。 7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因 而无法作为索引选择的输入项。如下面语句将进行全表扫描: select id from t where num=@num 可以改为强制查询使用索引: select id from t with(index(索引名)) where num=@num 8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用 索引而进行全表扫描。如:

SQL语句执行顺序

一、sql语句的执行步骤: 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。 3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。 4)表达式转换,将复杂的 SQL 表达式转换为较简单的等效连接表达式。 5)选择优化器,不同的优化器一般产生不同的“执行计划” 6)选择连接方式,ORACLE有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。7)选择连接顺序,对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。 8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。 9)运行“执行计划” 二、oracle 共享原理: ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用 三、oracle 语句提高查询效率的方法:1: where column in(select * from ... where ...); 2:... where exists (select 'X' from ...where ...); 第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间 Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中避免使用having字句避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销 SQL Select语句完整的执行顺序: 1、from子句组装来自不同数据源的数据; 2、where子句基于指定的条件对记录行进行筛选; 3、group by子句将数据划分为多个分组; 4、使用聚集函数进行计算; 5、使用having子句筛选分组; 6、计算所有的表达式; 7、使用order by对结果集进行排序。

执行一条sql语句update多条记录实现思路

执行一条sql语句update多条记录实现思路 如果你想更新多行数据,并且每行记录的各字段值都是各不一样,怎么办? 通常情况下,我们会使用以下SQL语句来更新字段值: UPDATE mytable SET myfield='value' WHERE other_field='other_value'; 但是,如果你想更新多行数据,并且每行记录的各字段值都是各不一样,你会怎么办呢?举个例子,我的博客有三个分类目录(免费资源、教程指南、橱窗展示),这些分类目录的信息存储在数据库表categories中,并且设置了显示顺序字段 display_order,每个分类占一行记录。如果我想重新编排这些分类目录的顺序,例如改成(教程指南、橱窗展示、免费资源),这时就需要更新categories表相应行的display_order字段,这就涉及到更新多行记录的问题了,刚开始你可能会想到使用循环执行多条UPDATE语句的方式,就像以下的php 程序示例: ? 1 2 3 4 5 foreach ($display_order as $id => $ordinal) { $sql="UPDATE categories SET display_order = $ordinal WHERE id = $id"; mysql_query($sql); } 这种方法并没有什么任何错误,并且代码简单易懂,但是在循环语句中执行了不止一次SQL 查询,在做系统优化的时候,我们总是想尽可能的减少数据库查询的次数,以减少资源占用,同时可以提高系统速度。 幸运的是,还有更好的解决方案,下面列举两种常用的方案只不过SQL语句稍微复杂点,但是只需执行一次查询即可,语法如下: ? 1 2 3 4 5 6 7 8 ?第一种:IF--THEN语句结合UPDATE mytable SET myfield = CASE other_field WHEN 1 THEN 'value' WHEN 2 THEN 'value' WHEN 3 THEN 'value' END

6异常及其处理_知识点

异常及其处理. 一.异常处理概述 在运行过程中,应用程序可能遇到各种错误。例如,从一个已经关闭的流读数据;访问数组时数组下标越界;使用空引用调用方法等。 许多程序员不检查可能的错误,理由是如果每执行一个语句都检查是否出错,将使程序的结构混乱,难以理解。 为了解决程序的正确性和程序结构的清晰性之间的矛盾,程序设计语言引入了异常及异常处理机制。下面是java语言的异常处理机制的粗略过程: 1.程序运行时出错,抛出异常对象.当程序执行过程中出现错误(例如0做除数,数组下标越界等)时,系统会自动创建一个对象(称作异常对象,包含出错信息)并且抛出这个对象,或者在程序执行期间遇到无法继续执行的情况(例如打开文件失败,连接数据库失败等),程序员可以创建一个异常对象,然后使用throw语句抛出这个异常对象。 2.终止程序的正常执行顺序,转去查找处理该异常的代码.只要有异常对象E被抛出(无论是由系统抛出的还是由throw语句抛出的),程序就立即停止正常的执行顺序,转去查找处理异常对象E的代码。查找策略是首先在当前方法中查找,没有找到则本方法结束,到调用该方法的方法中继续查找,如果一直查找到main方法也没有找到处理该异常的代码,打印堆栈踪迹后程序结束。 3.处理异常.如果在调用链的某个方法中找到处理这个异常的代

码,则执行这段代码以及之后的代码。 与异常处理有关的语句是throw语句,try-catch-finally语句和Throwable类及其子类。 二. throw语句 语法:throw expression; 这里throw是保留字,expression是一个表达式,它的值一定是某个Throwable类对象的引用。throw语句的功能是:计算表达式得到一个Throwable对象的引用e,抛出e使得系统进入异常处理状态,查找处理该类异常的catch子句。如果找到这样的catch子句,系统恢复到正常执行程序的状态,开始处理异常;如果一直找不到处理该类异常的catch子句,线程终止。 例.看下面代码段 //创建Throwable对象,系统并不进入异常处理状态 Throwable e=new Throwable(); ……//其它代码,系统正常执行这些代码 //抛出异常,系统进入异常处理状态,查找处理e的代码。 if (B) throw e; else ……//系统仍旧处于正常执行程序的状态,执行这些代码。 三. try-catch-finally语句 语法1: try

oracle sql语句执行顺序

要知道SQL语句,我想我们有必要知道SQL Server查询分析器怎么执行我们的SQL语句的,我们很多人会看执行计划,或者用Profiler来监视和调优查询语句或者存储过程慢的原因,但是如果我们知道查询分析器的执行逻辑顺序,下手的时候就胸有成竹,那么下手是不是有把握点呢? 一、查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_condition (4) WHERE where_condition (5) GROUP BY group_by_list (6) WITH {cube | rollup} (7) HAVING having_condition (8) SELECT (9) DISTINCT (11) top_specification select_list (9) ORDER BY order_by_list 标准的SQL 的解析顺序为: (1) FROM 子句组装来自不同数据源的数据 (2) WHERE 子句基于指定的条件对记录进行筛选 (3) GROUP BY 子句将数据划分为多个分组 (4) 使用聚合函数(avg)进行计算 (5) 使用HAVING子句筛选分组 (6) 计算所有的表达式 (7) 使用ORDER BY对结果集进行排序 二、执行顺序 1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1 2. ON: 对vt1表应用ON筛选器只有满足join_condition 为真的行才被插入vt2 3. OUTER(join):如果指定了OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束。 4. WHERE:对vt3应用WHERE 筛选器只有使where_condition 为true的行才被插入vt4 5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5 6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6 7. HAVING:对vt6应用HAVING筛选器只有使having_condition 为true的组才插入vt7 8. SELECT:处理select列表产生vt8 9. DISTINCT:将重复的行从vt8中去除产生vt9 10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10 11. TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者 看到这里,那么用过Linq to SQL的语法有点相似啊?如果我们我们了解了SQL Server 执行顺序,那么我们就接下来进一步养成日常SQL的好习惯,也就是在实现功能的同时有考虑性能的思想,数据库是能进行集合运算的工具,我们应该尽量的利用这个工具,所谓集合运算实际就是批量运算,就是尽量减少在客户端进行大数据量的循环操作,而用SQL语句或者存储过程代替。 三、只返回需要的数据 返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户

fpga第六章作业及答案

第6章PPT课件作业 1.顺序语句和并行语句分别有哪些?顺序语句和并行语句主要有什么区别? 答:顺序执行语句是顺序执行的,只能出现在进程和子程序中,用于定义进程的算法。顺序描述语句主要有:信号赋值语句、变量赋值语句、if语句、case语句、wait语句和null语句。结构体中的并行语句主要有6种:并行信号赋值语句、进程语句、块语句、元件例化语句、生成语句、并行过程调用语句; 区别主要在于:在执行顺序上,顺序语句是顺序执行的,if语句一定要在顺序结构中,有优先级;并行语句在结构体内是并行执行的。在赋值上,顺序语句可对变量和信号赋值,并行语句的赋值目标必须为信号或端口,在结构体的进程之外使用。 2.阅读下面的程序,分析其实现的逻辑功能,并说明是时序逻辑还是组合逻辑 library ieee; Use ieee.std_logic_1164.all; Entity decoder is Port (a : in std_logic_vector(9 downto 0); c : out integer range 0 to 9); end Entity decoder ; architecture one of decoder is begin with a select c<=0 when “0000000001” , 1 when “0000000010” , 2 when “0000000100” , 3 when “0000001000” , 4 when “0000010000” , 5 when “0000100000” , 6 when “0001000000” , 7 when “0010000000” , 8 when “010*******” , 9 when “1000000000” , 0 when others ; end architecture one; 答:功能:是10位2进制的部分译码器。由1出现的位置来决定译码器输出的是数字几。当右边的第一位是一时,输出0,第二位是1时输出1,以此类推直到输出9.其余的编码都是输出0。由于没有用到ckl所以使用的是组合逻辑。 3.结构体的描述方式有几种方式?各有什么特点? 答:结构体有三种描述方式,即行为级描述:是对整个设计单元的数学模型描 述,属于一种高层次描述方式;数据流级描述:采用进程语句控制数据流在控

SQL语句执行效率及分析(note)

SQL语句执行效率及分析(note) 1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2000 目的: 查询性能测试,比较两种查询的性能 SQL查询效率step by step -- setp 1. -- 建表 create table t_userinfo ( userid int identity(1,1) primary key nonclustered, nick varchar(50) not null default '', classid int not null default 0, writetime datetime not null default getdate() ) go -- 建索引 create clustered index ix_userinfo_classid on t_userinfo(classid) go -- step 2. declare @i int declare @k int declare @nick varchar(10) set @i = 1 while @i<1000000 begin set @k = @i % 10 set @nick = convert(varchar,@i) insert into t_userinfo(nick,classid,writetime) values(@nick,@k,getdate()) set @i = @i + 1

end -- 耗时08:27 ,需要耐心等待 -- step 3. select top 20 userid,nick,classid,writetime from t_userinfo where userid not in ( select top 900000 userid from t_userinfo order by userid asc ) -- 耗时8 秒,够长的 -- step 4. select https://www.doczj.com/doc/3411445876.html,erid,b.nick,b.classid,b.writetime from ( select top 20 https://www.doczj.com/doc/3411445876.html,erid from ( select top 900020 userid from t_userinfo order by userid asc ) a order by https://www.doczj.com/doc/3411445876.html,erid desc ) a inner join t_userinfo b on https://www.doczj.com/doc/3411445876.html,erid = https://www.doczj.com/doc/3411445876.html,erid order by https://www.doczj.com/doc/3411445876.html,erid asc -- 耗时1 秒,太快了吧,不可以思议 -- step 5 where 查询 select top 20 userid,nick,classid,writetime from t_userinfo where classid = 1 and userid not in ( select top 90000 userid from t_userinfo where classid = 1 order by userid asc ) -- 耗时2 秒 -- step 6 where 查询 select https://www.doczj.com/doc/3411445876.html,erid,b.nick,b.classid,b.writetime from ( select top 20 https://www.doczj.com/doc/3411445876.html,erid from ( select top 90000 userid from t_userinfo

EDA电子科大版简答填空考试要点

EDA电子科大版简答填空考试要点 1.VHDL程序一般包括几个组成部分?每部分的作用是什么? 三个基本组成部分:库、程序包使用说明,实体描述和实体对应的结构体描述(必要时还包括结构体的配置) 库、程序包使用说明-用于打开调用本设计实体将用到的库、程序包。 实体描述----------用于描述该设计实体与外界的接口信号说明。 结构体描述--------用于描述该设计实体内部的组成及内部工作的逻辑关系。 结构体配置语句主要用于层次化的方式对特定的设计实体进行元件的例化,或是为实体选定某个特定的结构体 2.库由哪些部分组成?在VHDL语言中常见的有哪几种?编程人员怎样使用已有的库? 库由多个包含已定义的函数,数据类型,元件调用说明及子程序的程序包组成,常见的库有如下四种 IEEE库、WORK库、STD库、VITAL库使用方式如下 LIBRARY 库名 3.在VHDL中常用到的预定义程序包有哪几个?怎样使用这些程序包? 常见的预定义程序包有四种:STD_LOGIC_1164,STD_LOGIC_ARITH,STD_LOGIC_UNSIGNED和STD_LOGIC_SIGNED,STANDARD和TEXTIO 使用这些程序报的方法:USE 库名.程序包.项目名/ALL; 4.VHDL语言中的数据对象有几种?各种数据对象的作用范围如何?各种数据对象的实际物理意义是什么? 数据对象有三种:常量、变量、信号 常量使用的范围取决于被定义的位置。在程序包中定义的敞亮具有全局最大化的特征,可以在调用此程序包的所有实体中应用;定义在设计实体的常量,其有效范围为在这个实体定义的所有结构体;定义在设计实体的某一结构体的常量,只能用于此结构体;定义在结构体的某一单元的常量如在一个进程中,只能用在这个进程中。 变量只能使用在进程和子程序中,其使用范围仅限于被定义的变量的进程和子程序中。 信号具有全局特性。 常量相当于电路中的恒定电平,而变量和信号相当于组合电路系统中门与门间的连接及其连线的信号值。 5.什么是标识符?在VHDL的基本标识符是怎么规定的? 标识符用来定义常量、变量、信号、端口、子程序或者参数的名字。 VHDL基本标识符就是以英文字母开头,不连续使用下划线_,不以下划线结尾的,由26个英文大小写字母,数字0-9以及下划线_组成的字符串。 6.信号和变量在描述和使用时有哪些主要的区别? 信号和变量的主要区别表现在接受和保持信息的方式,信息保持和传递的区域大小上。

第五章 异常

第一部分 知识点总结
一,错误的种类 1. 语法错误 2. 运行时错误:异常 3. 逻辑错误 二,异常 1. 运行时发生的错误 2. 发生异常时,程序突然终止,并将控制权传递给操作系统,即出现异常时,会提示错误,然后程序不再往 后执行. 3. 设计良好的程序应该在异常发生时提供处理这些错误的方法,使得程序不会因为异常的发生而阻断或产生 不可预见的结果 4. Java 程序的执行过程中如果出现异常,可以生成一个异常类对象,该对象封装了异常事件的信息并将被提 交给 Java 运行时系统,这个过程称为抛出异常 5. 当 Java 运行时系统接收到的异常对象时, 会寻找能处理这一异常的代码, 并把当前的异常对象交给其处理, 这一过程称为捕获异常 6. 异常处理时用到的关键字:try,catch,finally,throw,throws try, try catch,finally,throw, 三,异常类 1.类的层次结构 Throwable 类 a) Error:此类错误通常不会设计程序去捕获并处理 b) Exception:一般性的错误,通常捕获后可做处理,以确保程序继续运行 i. 其他异常类:必须处理,否则无法运行 ii. RuntimeException(发生频率比较高的异常,可以处理也可以不处理) 1. ArithmeticException:数学类异常 2. ArrayIndexOutOfBoundsException:数组下标越界异常 3. NullPointerException:空指针异常 4. ClassNotFoundException:找不到类异常 5. NumberFormatException:数字格式异常 2.异常类的方法 1) printStackTrace() :用来显示有关的异常信息,包括异常的原因和出现异常的代码行 2) getMessage() :用于获得产生异常的错误性质 四,异常处理的使用 1. 异常处理的代码格式 try{ 要监控的程序语句,即可能出现异常的语句 } catch(异常类型 对象){ 以合理的方式捕获和处理异常 若 try 块中的语句没有出错,则不会执行此块代码 } finally{ 释放资源,无论是否出现异常,都会执行此块代码 } 格式说明: 1) finally 块不是必须有的,如果有,必须和 try…catch 块连用

解析SQL执行过程

为了将用户写的SQL文本转化为Oracle认识的且可执行的语句,这个过程就叫做解析过程。解析分为硬解析和软解析。一条SQL语句在第一次被执行时必须进行硬解析。 当客户端发出一条SQL语句(也可以是一个存储过程或者一个匿名PL/SQL块)进入shared pool时(注意,我们从前面已经知道,Oracle对这些SQL不叫做SQL语句,而是称为游标。因为Oracle在处理SQL时,需要很多相关的辅助信息,这些辅助信息与SQL语句一起组成了游标),Oracle首先将SQL文本转化为ASCII值,然后根据hash函数计算其对应的hash值(hash_value)。根据计算出的hash值到library cache中找到对应的bucket,然后比较bucket里是否存在该SQL语句。 如果不存在,则需要按照我们前面所描述的,获得shared pool latch,然后在shared pool 中的可用chunk链表(也就是bucket)上找到一个可用的chunk,之后释放shared pool latch。在获得了chunk以后,这块chunk就可以认为是进入了library cache。接下来,进行硬解析过程。硬解析包括以下几个步骤。 对SQL语句进行文法检查,看是否有文法错误。比如没有写from、select拼写错误等。如果存在文法错误,则退出解析过程。 到数据字典里校验SQL语句涉及的对象和列是否都存在。如果不存在,则退出解析过程。这个过程会加载dictionary cache。 将对象进行名称转换。比如将同名词翻译成实际的对象等。比如select * from t中,t是一个同名词,指向hr.t1,于是Oracle将t转换为hr.t1。如果转换失败,则退出解析过程。 检查发出SQL语句的用户是否具有访问SQL语句里所引用的对象的权限。如果没有权限,则退出解析过程。 通过优化器创建一个最优的执行计划。这个过程会根据数据字典里记录的对象的统计信息,来计算最优的执行计划。这一步牵涉大量数学运算,是最消耗CPU资源的。 将该游标所产生的执行计划、SQL文本等装载进library cache的heap中。 在硬解析的过程中,进程会一直持有library cache latch,直到硬解析结束为止。硬解析结束以后,会为SQL语句产生两个游标,一个是父游标,另一个是子游标。父游标里主要包含两种信息:SQL文本以及优化目标(optimizer goal)。父游标在第一次打开时被锁定,直到其他所有的session都关闭该游标后才被解锁。当父游标被锁定的时候是不能被交换出library cache的,只有在解锁以后才能被交换出library cache。父游标被交换出内存时,父游标对应的所有子游标也被交换出library cache。子游标包括游标所有的信息,比如具体的执行计划、绑定变量等。子游标随时可以被交换出library cache,当子游标被交换出library cache

第12章 异常处理 习题

第12章异常处理 一.单项选择题 1.程序中的错误可以分为以下三类,除了【】。 A) 逻辑错误B) 运行错误C) 自定义错误D) 语法错误2.程序运行期间发生的错误称为【】。 A) 版本B) 断点C) 异常D) 属性 3.在C#程序中,可以使用try…catch机制来处理程序出现的【】错误。 A) 语法B) 拼写C) 运行D) 逻辑 4.以下关于C#的异常处理的叙述中,正确的是【】。 A) 一个try块后面只能跟随一个catch块 B) 在try…catch…finally块中,当发生异常时只执行相应catch块中的语句,不会执行finally块 C) throw语句中必须指出抛出的异常 D) try块后面必须跟catch块或finally块组合使用,不能单独使用 5.以下关于try…catch…finall语句的叙述中,不正确的是【】。 A) catch块可以有多个B) finally块最多只能有一个 C) catch块和finally块都是可选的D) 可以只有try块,没有catch块和finally 块 6.一般情况下,异常类存放在【】中。 A) System.Exception命名空间B) System.Diagnostics命名空间 C) System命名空间D) Exception命名空间 7.分析下列程序代码: int num; try { num= Convert.ToInt32(Console.ReadLine());} Catch { //捕获异常} 当输入"abc"时,会抛出【】异常。 A) FormatException B) IndexOutOfRangException C) OverflowException D) TypeLoadException 8.用户定义的异常应该从【】类中继承。 A) ArgumentException B) IOException C) SystemException D) Exception 9..NET Framework中,处理异常是很有用的功能。一个try代码块可以有多个catch块与之对应。在多个catch块中,下面【】异常应该最后捕获。 A) Exception B) StackOverflowException C) SystemException D) FormatException 10.下列关于try…catch…finally语句的说明中,不正确的是【】。 A) catch块可以有多个B) finally块是可选的 C) catch块是可选的D) 可以只有try块 11.为了能够在程序中捕获所有异常,在catch语句的括号中使用的类名为【】。

PLSQL怎么执行SQL语句

通过f5查看到的执行计划,其实是pl/sql developer工具内部执行查询 plan_table表然后格式化的结果。 select * from plan_table where statement_id=...。其中 description列描述当前的数据库操作, object owner列表示对象所属用户, object name表示操作的对象, cost列表示当前操作的代价(消耗),这个列基本上就是评价sql语句的优劣,cardinality列表示操作影响的行数, bytes列表示字节数篇二:plsqldeveloper工具使用教程 plsql入门 pl/sql的概述 pl/sql的优势 pl/sql是一种块结构的语言,允许你将业务逻辑封装在一起,这是到目前为止使用pl/sql的最大优势 pl/sql是在服务器上运行,可以与数据库和sql引擎直接进行交互, pl/sql是什么? (procedural language/sql) 是oracle在标准的sql语言上的扩展,pl/sql不仅允许嵌入sql语言,还可以定义变量和常量,允许使用条件语句和循环语句,允许使用列外处理各种错误,这样使得它的功能变得更加强大。 特性: 减少java程序的复杂性 一.过程,函数,触发器是pl/sql编写的 二.过程、函数、触发器是在oracle中 三. pl/sql是非常强大的数据库过程语言 四.过程,函数可以再java程序中调用 为什么学? a) 提高应用程序的运行性能 b) 模块化的设计思想[分页的过程,订单的过程,转账的过程] c) 减少网络传输量(传统的方法,用sql语句传输!现在就只需要调用存储过程) d) 提高安全性(传统sql 可以看到表名字段等…) 不好: 移植性不好,(你写好的存储过程,函数等当我们要换数据库时,这些东西就没用了)开发工具: 1. sqlplus 开发工具 是oracle公司提供的一个工具,这个因为我们在以前介绍过: 2. pl/sql developer开发工具 pl/sql developer是用于开发pl/sql块的集成开发环境(ide) 它是一个独立的产品,而不是oracle的一个附带品, createprocedure sp_pro1//存储过程名字 is begin ---执行部分 insert into mytest values(‘’,’’); end; / 查看错误信息

oracle-SQL语句执行原理和完整过程详解

SQL语句执行过程详解 一条sql,plsql的执行到底是怎样执行的呢? 一、SQL语句执行原理: 第一步:客户端把语句发给服务器端执行 当我们在客户端执行select 语句时,客户端会把这条SQL 语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作,他的主要任务就是把客户端产生的一些SQL 语句发送给服务器端。虽然在客户端也有一个数据库进程,但是,这个进程的作用跟服务器上的进程作用事不相同的。服务器上的数据库进程才会对SQL 语句进行相关的处理。不过,有个问题需要说明,就是客户端的进程跟服务器的进程是一一对应的。也就是说,在客户端连接上服务器后,在客户端与服务器端都会形成一个进程,客户端上的我们叫做客户端进程;而服务器上的我们叫做服务器进程。 第二步:语句解析 当客户端把SQL 语句传送到服务器后,服务器进程会对该语句进行解析。同理,这个解析的工作, 其会做很多小动作。 也是在服务器端所进行的。虽然这只是一个解析的动作,但是,“” 1. 查询高速缓存(library cache)。服务器进程在接到客户端传送过来的SQL 语句时,不 会直接去数据库查询。而是会先在数据库的高速缓存中去查找,是否存在相同语句的执行计划。如果在数据高速缓存中,则服务器进程就会直接执行这个SQL 语句,省去后续的工作。所以,采用高速数据缓存的话,可以提高SQL 语句的查询效率。一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高,另一方面,也是因为这个语句解析的原因。 不过这里要注意一点,这个数据缓存跟有些客户端软件的数据缓存是两码事。有些客户端软件为了提高查询效率,会在应用软件的客户端设置数据缓存。由于这些数据缓存的存在,可以提高客户端应用软件的查询效率。但是,若其他人在服务器进行了相关的修改,由于应用软件数据缓存的存在,导致修改的数据不能及时反映到客户端上。从这也可以看出,应用软件的数据缓存跟数据库服务器的高速数据缓存不是一码事。 2. 语句合法性检查(data dict cache)。当在高速缓存中找不到对应的SQL 语句时,则服 务器进程就会开始检查这条语句的合法性。这里主要是对SQL 语句的语法进行检查,看看其是否合乎语法规则。如果服务器进程认为这条SQL 语句不符合语法规则的时候,就会把这个错误信息,反馈给客户端。在这个语法检查的过程中,不会对SQL 语句中所包含的表名、列名等等进行SQL 他只是语法上的检查。 3. 语言含义检查(data dict cache)。若SQL 语句符合语法上的定义的话,则服务器进程 接下去会对语句中的字段、表等内容进行检查。看看这些字段、表是否在数据库中。如果表名与列名不准确的话,则数据库会就会反馈错误信息给客户端。所以,有时候我们写select 语句的时候,若语法与表名或者列名同时写错的话,则系统是先提示说语法错误,等到语法完全正确后,再提示说列名或表名错误。 4. 获得对象解析锁(control structer)。当语法、语义都正确后,系统就会对我们需要查询的对象加锁。这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象的结构发生改变。 5. 数据访问权限的核对(data dict cache)。当语法、语义通过检查之后,客户端还不一定 能够取得数据。服务器进程还会检查,你所连接的用户是否有这个数据访问的权限。若你连接上服务器

5VHDL顺序语句与并行语句

5 VHDL 顺序语句与并行语句 电子信息工程学院 顺序语句与并行语句 大纲 进程语句 顺序语句 并行语句 2 2 电子信息工程学院 顺序语句与并行语句 VHDL 程序设计约定 语句结构描述中方括号“[ ]”内的内容为可选内容。 对于VHDL 的编译器和综合器来说,程序文字的大小写是不加区分的。 程序中的注释使用双横线“--”。 QuartusII 要求源程序文件的名字与实体名、工程名必须一致。 编写程序注意不要在中文输入状态下输入英文字符和符号。 为了使程序结构清晰,使用层次缩进格式书写代码。 3 电子信息工程学院 顺序语句与并行语句 概述 顺序语句仅出现在进程和子程序中。 在结构体中的执行是同时进行,执行顺序与书写顺序无关。 4 电子信息工程学院 顺序语句与并行语句 进程语句(PROCESS ) ● 进程本身是并行语句,但内部是顺序语句; ● 进程只有在特定的时刻(敏感信号发生变化)才会被激活。 [进程标号:] PROCESS (敏感信号参数表) [声明区]; BEGIN 顺序语句 END PROCESS [进程标号]; 在进程中起作用的局部变量 一个进程可以有多个敏感信号,任一敏感信号发生变化都会激活进程 进程语句定义顺序语句模块,用于将从外部获得的信号值,或内部的运算数据向其他的信号进行赋值。 5 电子信息工程学院 顺序语句与并行语句 进程的工作原理 当某个敏感信号的值发生变化时,每个进程语句立即完成进程内顺序语句所定义的功能行为。 执行过程终止 顺序语句所定义的功能行为的结果可以赋值给信号,并通过信号被其他的进程读取或赋值。 6

电子信息工程学院 顺序语句与并行语句 进程与时钟 在每个上升沿启动一次进程(执行进程内所有的语句)。 上升沿描述:Clock’ EVENT AND Clock=‘1’ 下降沿描述:Clock’ EVENT AND Clock=‘0’ 上升沿描述: rising_edge (Clock) 下降沿描述: falling_edge (Clock) 7 电子信息工程学院 顺序语句与并行语句 进程语句格式与结构 [进程标号: ] PROCESS [ ( 敏感信号参数表 ) ] [IS] [进程说明部分] BEGIN 顺序描述语句 END PROCESS [进程标号]; PROCESS 语句结构 进程说明 顺序描述语句 敏感信号参数表 信号赋值语句 变量赋值语句 进程启动语句 子程序调用语句 顺序描述语句 进程跳出语句 8 电子信息工程学院 顺序语句与并行语句 1. PROCESS 为一无限循环语句 2. PROCESS 中的顺序语句具有明显的顺序/并行运行双重性 3. 进程语句本身是并行语句 4. 信号是多个进程间的通信线 5. 一个进程中只允许描述对应于一个时钟信号的同步时序 逻辑 进程要点 9 电子信息工程学院 顺序语句与并行语句 进程注意事项 ● 进程本身是并行语句,但内部为顺序语句; ● 进程在敏感信号发生变化时被激活,在使用了敏感表的进程中不能含wait 语句; ● 在同一进程中对同一信号多次赋值,只有最后一次生效; ● 在不同进程中,不可对同一信号进行赋值; ● 一个进程不可同时对时钟上、下沿敏感。 ● 进程中的信号赋值是在进程挂起时生效的,而变量赋值是即时生效。 ● 相对于结构体而言,信号具有全局性,是进程间进行并行联系的重要途径。 ● 进程为综合器支持,且其建模方式直接影响仿真和综合结果,综合后对应于进程的硬件结构对进程中所有可读入信号都是敏感的。 ENTITY test IS PORT (clock: IN BIT; A: IN Integer RANGE 0 TO 7; B: OUT Integer RANGE 0 TO 7); END test; ARCHITECTURE a OF test IS BEGIN PROCESS(clock) BEGIN IF clock'event and clock='1' THEN B<=A+1;B<=3; END IF; END PROCESS; END; PROCESS (Clock) BEGIN IF rising_edge (Clock) THEN : ELSIF falling_edge (Clock) THEN ; : END IF ; END PROCESS ; 10 电子信息工程学院 顺序语句与并行语句 例程 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ENTITY test IS PORT (clock: IN BIT; A: IN Integer RANGE 0 TO 7; B: OUT Integer RANGE 0 TO 7); END test; ARCHITECTURE a OF test IS Signal C: Integer RANGE 0 TO 7; BEGIN PROCESS(clock) BEGIN IF clock'event and clock='1' THEN C<=A+1; B<=C; C<=3; END IF; END PROCESS; END; 互换位置,观察B 值变化。 调整位置,观察B 值变化。 删除,观察是否有影响。 赋初值,观察波形变化。 11 电子信息工程学院 顺序语句与并行语句 例程—分频器 LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL; ENTITY FreDevider IS PORT ( Clock: IN Std_logic; Clkout: OUT Std_logic); END; ARCHITECTURE Behavior OF FreDevider IS SIGNAL Clk: Std_Logic; BEGIN PROCESS (Clock) --将时钟作为进程的敏感信号 BEGIN IF rising_edge (Clock) THEN Clk<=NOT Clk; --在时钟上升沿执行Clk<=NOT Clk END IF; END PROCESS; Clkout<=Clk; END; 12

相关主题
文本预览
相关文档 最新文档