Oracle大量数据查询优化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle大量数据查询优化相关的知识,希望对你有一定的参考价值。
比如sql为“select name from table”name字段名,table表名如果数据量很大 几百万的有什么优化的方法数据库是Oracle的
参考技术A 首先,对语句进行优化,不要尽量不要写过于复杂的嵌套查询,当需要的时候,后面的子查询数量应为较大的数据。因为SQL是从右至左的查询,先查大的数据。然后建立索引,对经常查到的条件字段 例如 时间 where 月份 = 1月 这样的语句就应该建立所以 来提高效率。对于较复杂的查询应建立组合索引。横纵向切割表。对于大数据量,上百万条的数据可以对其进行横向切割。比如按时间的月份进行切割,或者按照其他方式来切割表,达到快速查询的目的。减少信息的检索量。 参考技术B 1、在表上建分区;2、建索引;
3、如果是exedata平台,不要用索引,尽量少用hint;
4、用并行; 参考技术C 1、name上建立索引
2、将表table在线重定义为分区表,在name列上使用hash分区或者range分区 参考技术D create index(es). but, you should have the "where clause" in the statement to use the index
如何做SqlServer 数据查询优化!
一、建立索引二、建立存储过程
三、只查询您所需要的数据,不要把所有数据都查询出来,防止数据冗余。
四、对于大量及海量数据一般还要建立分区 参考技术A 有很多种优化,索引\分区是常用优化方法。 参考技术B 1、适当的建立索引
2、规范查询语句
3、sql语句中尽量用参数,以便使用计划
4、拆分表,表分区 参考技术C 影响查询效率的因素
SQLServer处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给SQLServer的查询优化器,查询优化器通过检查索引的存在性、有效性和基于列的统计数据来决定如何处理扫描、检索和连接,并生成若干执行计划,然后通过分析执行开销来评估每个执行计划,从中选出开销最小的执行计划,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。所以,SQLServer中影响查询效率的因素主要有以下几种:
1.没有索引或者没有用到索引。索引是数据库中重要的数据结构,使用索引的目的是避免全表扫描,减少磁盘I/O,以加快查询速度。
2.没有创建计算列导致查询不优化。
3.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。
4.返回了不必要的行和列。
5.查询语句不好,没有优化。其中包括:查询条件中操作符使用是否得当;查询条件中的数据类型是否兼容;对多个 表查询时,数据表的次序是否合理;多个选择条件查询时,选择条件的次序是否合理;是否合理安排联接选择运算等。
SQLServer数据查询优化方法
3.1建立合适的索引 索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引,数据库也能根据SELECT语句成功地检索到结果,但随着表变得越来越大,使用“适当”的索引的效果就越来越明显。索引的使用要恰到好处,其使用原则有:
(1)对于基本表,不宜建立过多的索引;
(2)对于那些查询频度高,实时性要求高的数据一定要建立索引,而对于其他的数据不考虑建立索引;
(3)在经常进行连接,但是没有指定为外键的列上建立索引;
(4)在频繁进行排序或分组(即进行groupby或 orderby操作)的列上建立索引;
(5)在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度;
(6)如果待排序的列有多个,可以在这些列上建立复合索引。 在SQLServer中,索引按索引表达式包含的列分为单列索引和复合索引。检查查询语句的where子句,因为这是优化器重要关注的地方。包含在where里面的每一列都是可能的侯选索引,为能达到最优的性能,例如:对于在where子句中给出了 column1这个列,下面的两个条件可以提高索引的优化查询性能!
第一:在表中的column1列上有一个单索引;
第二:在表中有多索引,但是 column1是第一个索引的列。避免定义多索引而column1是第二个或后面的索引,这样的索引不能优化服务器性能。例如:下面的例子用了pubs数据库。 SELECTau_id,au_lname,au_fname FROMauthorsWHEREau_lname=’White’ 按下面几个列上建立的索引将会是对优化器有用的索引 au_lname au_lname,au_fname 而在下面几个列上建立的索引将不会对优化器起到好的作用 au_address au_fname,au_lname 在SQLServer中,索引按存储结构分为聚簇索引和非聚簇索引。聚簇索引是按照定义数据列值的顺序在物理上对记录排序,在一个表上只能有一个聚簇索引,聚簇索引查询速度较快,但缺点是对表进行修改操作时速度较慢,因为为了保证表中记录的物理顺序与索引的顺序一致,必须将记录插入到数据页的相应位置,从而数据页中的数据必须重排。在下面的几个情况下,可以考虑用聚簇索引:
(1)某列包括的不同值的个数是有限的(但是不是极少的)。如顾客表的州名列有50个左右的不同州名的缩写值,可以使用聚簇索引。
(2)对返回一定范围内值的列可以使用聚簇索引,如用between,>,>=, Select*fromsaleswhereord_datebetween’5/1/93’and’6/1/93’
(3)对查询时返回大量结果的列可以使用聚簇索引。 SELECT*FROMphonebookWHERElast_name=’Smith’ 当有大量的行正在被插入表中时,要避免在本表一个自然增长(例如,identity列)的列上建立聚簇索引。如果你建立了聚簇的索引,那么insert的性能就会大大降低。因为每一个插入的行必须到表的最后,表的最后一个数据页。
非聚簇索引指定表中的逻辑顺序,一个表上可以建立多达249个非聚簇索引,它查询的速度比不建立索引快,但比聚簇索引慢,插入数据比聚簇索引快,因为纪录直接被追加到数据末尾。可以在以下情况下考虑使用非聚簇索引。
(1)在有很多不同值的列上可以考虑使用非聚簇索引,如employee表中的emp_id列可以建立非聚簇索引。
(2)查询结果集返回的是少量或单行的结果集。例如
select*fromemployeewhereemp_id=’pcm9809f’
(3)查询语句中orderby子句的列上可以考虑使用非聚簇索引。
3.2常用的计算字段(如总计、最大值等)可以考虑存储到数据库实体中。 例如仓库管理系统中有材料入库表,其字段为:材料编号、材料名称、型号,单价,数量…,而金额是用户经常需要在查询和报表中用到的,在表的记录量很大时,有必要把金额作为一个独立的字段加入到表中。这里可以采用触发器以在客户端保持数据的一致性。
3.3用where子句来限制必须处理的行数。 在执行一个查询时,用一个where子句来限制必须处理的行数,除非完全需要,否则应该避免在一个表中无限制地读并处理所有的行。例如: ||| select qty from sales where stor_id=’7131’是很有效的,比无限制的查询selectqtyfromsales有效,避免给客户的最后数据选择返回大量的结果集。当然也可以用TOP限制返回结果集的行数。
3.4尽量使用数字型字段。 一部分开发人员和数据库管理人员喜欢把包含数值信息的字段设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
3.5查询语句的优化。 对于一条复杂的查询语句来说,对相同查询条件的实现一般总可以有多种不同的表达方法,而不同的表达会使数据库的响应速度大相径庭。据统计,约有80%以上的性能问题是由于使用了不恰当的查询语句造成的,因此SQL语句的质量对整个系统效率有重大关系。
下面介绍查询语句优化方面的一些技巧:
(1)避免使用不兼容的数据类型。例如float和int、char和varchar、 binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如: SELECTnameFROMemployeeWHEREsalary>60000 在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。这条语句可以改为: SELECTnameFROMemployeeWHEREsalary>$60000
(2)尽量避免在Where条件里使用非聚合表达式,因为非聚合表达式很难利用到索引,通常SQLServer不得不进行大规模的扫描。像!=或<>、 ISNULL或ISNOTNULL、IN,NOTIN等这样的操作符构成的表达式都是非聚合表达式。非聚合表达式会导致查询效率大大降低。例如: SELECTidFROMemployeeWHEREid!='B%' 优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
(3)尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
SELECT*FROMemployeeWHEREsalary/2=100应改为:
SELECT*FROMemployeeWHEREsalary=100*2 SELECT*FROMemployeeWHERESUBSTRING(emp_id,1,3)=’PCM’应改为:
SELECT*FROMemployeeWHEREemp_idLIKE‘5378%’ SELECTmember_number,first_name,last_nameFROMmembers WHEREDATEDIFF(yy,datofbirth,GETDATE())>21应改为:
SELECT member_number,first_name,last_name FROM members WHERE dateofbirth 即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
(4)避免使用LEFTJOIN SQL的一个有价值的常用功能是LEFTJOIN。它可以用于检索第一个表中的所有行、第二个表中所有匹配的行、以及第二个表中与第一个表中不匹配的所有行。例如,如果希望返回每个客户及其定单,使用LEFTJOIN则可以显示有定单和没有定单的客户。LEFTJOIN消耗的资源非常之多,因为它们包含与 NULL(不存在)数据匹配的数据。因此在构造查询语句时尽量避免使用LEFTJOIN。
(5)尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。 见如下例子:
SELECT*FROMmembersWHEREfirst_nameLIKE‘%MA%’ SELECT*FROMmembersWHERESUBSTING(first_name,3,1)=’MA’ SELECT*FROMmembersWHEREfirst_nameLIKE‘MA%’ 即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。(6)避免相关子查询 一个列的标签同时在主查询和 WHERE子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。可 以采用子查询“展平”技术,将子查询转变为连接,半连接或反连接,从而达到优化查询的目的。例如查询找出有工资超过10000的职工所在的部门名称。 SELECT部门名FROM部门WHERE部门号IN (SELECT部门号FROM职工WHERE工资>10000) 此查询将扫描部门表的 每一行查找所有满足子查询条件的职工记录。可以将部门表作为连接的内表,在这种情况下,查询作为通常的连接来执行,首先对职工表进行唯一的部门号筛选,以 消除冗余的部门号,转化后的语句为: SELECTB.部门名FROM(SELECTDISTINCT部门号FROM职工WHERE工 资>10000,部门DWHEREB.部门号=D.部门号 对于SQL语句的优化方法还有很多,在这里就不一一例举了。 参考技术D 索引,重新写SQL。
以上是关于Oracle大量数据查询优化的主要内容,如果未能解决你的问题,请参考以下文章