Oracle,SQL语句中/*+ */是什么技术呢?
如:select /*+use_hash(a,b) */ a.* from .....
请教一下大家了
------解决方案--------------------这是oracle 中的哈希连接 。当内存能够提供足够的空间时,哈希(HASH)连接是Oracle优化器通常的选择。哈希连接中,优化器根据统计信息,首先选择两个表中的小表,在内存中建立这张表的基于连接键的哈希表;优化器再扫描表连接中的大表,将大表中的数据与哈希表进行比较,如果有相关联的数据,则将数据添加到结果集中。 当表连接中的小表能够完全cache到可用内存的时候,哈希连接的效果最佳。哈希连接的成本只是两个表从硬盘读入到内存的成本。 但是,如果哈希表过大而不能全部cache到可用内存时,优化器将会把哈希表分成多个分区,再将分区逐一cache到内存中。当表的分区超过了可用内存时,分区的部分数据就会临时地写到磁盘上的临时表空间上。因此,分区的数据写磁盘时,比较大的区间(EXTENT)会提高I/O性能。ORACLE推荐的临时表空间的区间是1MB。临时表空间的区间大小由UNIFORM SIZE指定。 当哈希表构建完成后,进行下面的处理: 1) 第二个大表进行扫描 2) 如果大表不能完全cache到可用内存的时候,大表同样会分成很多分区 3) 大表的第一个分区cache到内存 4) 对大表第一个分区的数据进行扫描,并与哈希表进行比较,如果有匹配的纪录,添加到结果集里面 5) 与第一个分区一样,其它的分区也类似处理。 6) 所有的分区处理完后,ORACLE对产生的结果集进行归并,汇总,产生最终的结果。 当哈希表过大或可用内存有限,哈希表不能完全CACHE到内存。随着满足连接条件的结果集的增加,可用内存会随之下降,这时已经CACHE到内存的数据可能会重新写回到硬盘去。如果出现这种情况,系统的性能就会下降。 当连接的两个表是用等值连接并且表的数据量比较大时,优化器才可能采用哈希连接。哈希连接是基于CBO的。只有在数据库初始化参数HASH_JOIN_ENABLED设为True,并且为参数PGA_AGGREGATE_TARGET设置了一个足够大的值的时候,Oracle才会使用哈希边连接。HASH_AREA_SIZE是向下兼容的参数,但在Oracle9i之前的版本中应当使用 HASH_AREA_SIZE。当使用ORDERED提示时,FROM子句中的第一张表将用于建立哈希表。 1. select a.user_name,b.dev_no 2.from user_info a, dev_info b 3. 4.where a.user_id = b.user_id; 5. 6.Plan 7. 8.---------------------- 9. 10.0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=3936 11. 12.) 13. 14.1 0 HASH JOIN (Cost=5 Card=82 Bytes=3936) 15. 16.2 1 TABLE ACCESS (FULL) OF 'USER_INFO' (Cost=2 Card=82 Bytes 17. 18.=1968) 19. 20.3 1 TABLE ACCESS (FULL) OF 'DEV_INFO' (Cost=2 Card=82 Bytes= 21. 22.1968) 可以通过在SQL语句中添加HINTS,强制ORACLE优化器产生哈希连接的执行计划。 1.select /*+ use_hash(a b)*/ a.user_name,b.dev_no 2. 3.from user_info a, dev_info b 4. 5.where a.user_id = b.user_id;
------解决方案--------------------哇 楼上好详细哈
我来概括一下,Oracle多表连接方式有3种
① neste loop join
② sort merge join
③ hash join (这也是10g缺省的连接方式)
对于三种连接,我们都可以使用hint来强制让优化器走:use_hash,use_nl,use_merge
------解决方案--------------------/*+ */ 相当于代码中的编译指令,要求oracle按照指定的某种规则执行,而不是使用默认设定
use_hash(a,b)是其中一种