说一下,什么是Oracle分区
分区的实质是把一张大表的数据按照某种规则使用多张子表来存储。
然后这多张子表使用统一的表名对外提供服务,子表实际对用户不可见。类似于在多张子
表上建立一个视图,然后用户直接使用该视图来访问数据。
Oracle 分区在什么情况下使用
当一张表的数据量到达上亿行的时候,表的性能会严重降低,这个时候就需要用到分区了
,通过划分成多个小表,并在每个小表上建立本地索引可以大大缩小索引数据文件的大小
,从而更快的定位到目标数据来提升访问性能。
分区除了可以用来提升访问性能外,还因为可以指定分区所使用的表空间,因此也用来做
数据的生命周期管理。当前需要频繁使用的活跃数据可以放到访问速度更快但价格也更贵
的存储设备上,而2、3年前的历史数据,或者叫冷数据可以放到更廉价、速度更低的设备上
。从而降低存储费用。
说一下,Oracle的分区有几种
Oracle的分区可以分为:列表分区、范围分区、散列分区(哈希分区)、复合分区。
范围分区
1、就是根据数据库表中某一字段的值的范围来划分分区。
2、数据中有空值,Oracle机制会自动将其规划到maxvalue的分区中。散列分区区(哈希分
区)
1、根据字段的hash值进行均匀分布,尽可能地实现各分区所散列的数据相等。
2、散列分区即为哈希分区,Oracle采用哈希码技术分区,具体分区如何由Oracle 说的算,也可能我
下一次搜索就不是这个数据了。
列表分区
列表分区明确指定了根据某字段的某个具体值进行分区,而不是像范围分区那样根据字段的值范围
来划分的。
复合分区
根据范围分区后,每个分区内的数据再散列地分布在几个表空间中,这样我们就要使用复合分区。
复合分区是先使用范围分区,然后在每个分区同再使用散列分区的一种分区方法。
在千万级的数据库查询中,如何提高效率?
分别从,从数据库设计方面,SQL优化语句方面说,物理优化方面说
1、从数据库设计方面说
2、从SQL优化语句方面说
3、物理优化方面说
数据库设计方面
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、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引
列有大量数据重复时,查询可能不会去利用索引,如一表中有字段sex,male、
female 几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
4、索引并不是越多越好,索引固然可以提高相应的select 的效率,但同时也降低
了insert及update的效率,因为insert或update时有可能会重建索引,所以怎样建索
引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应
考虑一些不常使用到的列上建的索引是否有必要。
5、应尽可能的避免更新索引数据列,因为索引数据列的顺序就是表记录的物理存
储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。
若应用系统需要频繁更新索引数据列,那么需要考虑是否应将该索引建为索引。
6、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降
低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐
个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
8、尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有
限(只有主键索引)。
9、避免频繁创建和删除临时表,以减少系统表资源的消耗。
10、临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需
要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用
导出表。
11、在新建临时表时,如果一次性插入数据量很大,那么可以使用select into 代
替create table,避免造成大量log ,以提高速度;如果数据量不大,为了缓和系
统表的资源,应先create table,然后insert。
12、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先
truncate table ,然后drop table ,这样可以避免系统表的较长时间锁定。
从SQL语句方面
1、应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进
行全表扫描。
2、应尽量避免在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
7、尽可能的使用varchar/nvarchar 代替char/nchar,因为首先变长字段存储空间小
,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然
要高些。
4、下面的查询也将导致全表扫描:select id from t where name like
'%abc%'
5、如果在where 子句中使用参数,也会导致全表扫描。因为SQL 只有在运行时
才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须
在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的
,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:select id
from t wherenum=@num 可 以 改 为 强 制 查 询 使 用 索 引 :selectidfromt
with(index(索引名))where num=@num
6、应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用
索引而进行全表扫描。
如:select id from t where num/2=100 应改为:select id from t where
num=100*2
7、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索
引而进行全表扫描。
如:select id from t where substring(name,1,3)='abc-name 以abc 开头的
id
select id from t where datediff(day,createdate,2005-11-30')=0-
1'2005-11-30'生成的id
应 改 为 :select id from t where name like
'abc%',select id from t where createdate>='2005-
11-30'and createdate<'2005-12-1'.
3、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