关联表查询和索引使用的探讨一则

今天碰到一个小的查询统计需求,总结一番确实有些意思。

在一张超多200万行的表中,需要查询在某个时段,符合全部10个类型的信息。即:

例如某个手机号码,在某个时段完成了全部10种类型的服务。注意,决对不能使用IN操作,是全部的10个都要符合条件。同事采用中间表分步提交再查询的方法。我想是否可以用一个SQL来完成呢?且性能要好。于是“旅程”开始了。

第一,其实这是一个比较典型的自连接操作。所以首次写了这样的SQL:

select * from

(select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '28') tab1,

(select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '29') tab2,

......

tab10

where tab1.src_terminal_id = tab2.src_terminal_id

and tab1.src_terminal_id = tab3.src_terminal_id

......

and tab1.src_terminal_id = tab10.src_terminal_id;

执行了很长时间,不对。停下来看,检查执行计划发现每一个嵌套的SQL都是基于全表扫描来完成查询!!注意当时的脚本中还没有使用TO_NUMBER这个函数。当时发现有时间范围搜索,立刻建立压缩索引,但是执行计划还是显示全部扫描?仔细看看,原来那个SEND_TIME字段是可空的VARCHAR2。经过询问知道实际业务中该字段是必须有值的。改不能为空,但是基于VARCHAR2的索引一旦使用大于小于这样的操作就会失效而直接使用全表扫描的。只好使用基于函数的INDEX了,于是就建立了基于TO_NUMBER(SEND_TIME)的一个索引。且另一个MMS_ZX_ID为低基数列字段,于是使用了BITMAP索引。

查看效果,计算的执行成本基本上是原来的10%!返回首行数据的时间由26S左右,下降到6S左右了。

开始执行,很长时间没有反馈,但是TEMP表空间却开始告急了。这个SQL基本吞噬了好几个G的空间。立刻停止!

看上去10个表的连接ORACLE处理起来确实费力。换换方法吧。

select tabb1.src_terminal_id

from (select tab1.src_terminal_id

from (select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '28') tab1,

(select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '29') tab2

where tab1.src_terminal_id = tab2.src_terminal_id) tabb1,

......

(select tab9.src_terminal_id

from (select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '37') tab9,

(select distinct src_terminal_id

from mms_seed_info_cdr_history t

where to_number(t.send_time) >= to_number('20080115000000')

and to_number(t.send_time) <= to_number('20080331000000')

and t.mms_zx_id = '38') tab10

where tab9.src_terminal_id = tab10.src_terminal_id) tabb5

where tabb1.src_terminal_id = tabb2.src_terminal_id

and tabb1.src_terminal_id = tabb3.src_terminal_id

and tabb1.src_terminal_id = tabb4.src_terminal_id

and tabb1.src_terminal_id = tabb5.src_terminal_id;

我先将两个表连接查询嵌套成一张表,10张表我做成5个嵌套表。然后这5张表再做连接查询。看看执行效果,共执行了75S,输出结果集。

通过这个SQL操作,我们不难看出,首先,INDEX的使用是需要讲究方式和方法的。但是可以肯定的是,一旦进行了数据类型转换操作,即使是隐性的,INDEX也会失效转而使用全部扫描了。再有就是表连接的数量,还是应该适当减少,可以通过嵌套的方式减少表连接数量,降低ORACLE内部操作复杂性,来提高执行速度。 -:)

------欢迎指正

©著作权归作者所有:来自51CTO博客作者Larry.Yue的原创作品,如需转载,请注明出处,否则将追究法律责任

oracle多表关联索引用法,关联表查询和索引使用的探讨一则相关推荐

  1. mysql 连接查询索引_Mysql (四)连接查询和索引

    一.什么是连接查询:就是将二个或二个以上的表,"连接起来"当做一个数据源,并从中去取得所须要的数据.连接查询包括交叉连接查询.内连接查询.外连接查询 (一)交叉连接:交叉连接不带W ...

  2. oracle查询不走索引的一些情况(索引失效)

    Oracle建立索引的目的是为了避免全表扫描,提高查询的效率. 但是有些情况下,即使建立了索引,但是执行写出来的查询还是很慢,然后通过执行计划会发现是索引失效导致的(不走索引,走全表扫描).所以需要了 ...

  3. mysql四种常用的索引_四种常见的索引类型

    主键索引:数据记录里面不能有 null,数据内容不能重复,在一张表里面不能有 多个主键索引. 普通索引:使用字段关键字建立的索引,主要是提高查询速度 唯一索引:字段数据是唯一的,数据内容里面能否为 n ...

  4. MySQL索引优化:索引失效以及不适合建立索引的场景

    引言: 索引是有双面性的,合理的建立索引可以提高数据库的效率.但是如果没有合理的构建索引和使用索引,可能会导致索引失效或者影响数据库性能,本文主要讨论的是索引失效以及不适合建立索引的场景 结论:具体案 ...

  5. Oracle\MS SQL Server的数据库多表关联更新UPDATE与多表更新

    一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.我们先来讨论根据其他表数据更新你要更新的表 一.MS    S ...

  6. mysql索引优化 - 多表关联查询优化

    1 left join EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card; LEFT JOIN条件用于确定如何从 ...

  7. Oracle 表关联、半关联、反关联

    一. 表关联 先建两个测试表 create table t1(id int,name varchar2(10)); create table t2(id int,name varchar2(10)); ...

  8. 【Oracle】record varray (associative array 关联数组) table (nested table type 嵌套表类型)和%type、%rowtype的使用详解

    官方文档: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/lnpls/plsql-data-types.html#GU ...

  9. Oracle 原理:高水位线、PCTFREE、PCTUSED、索引组织表、簇表、临时表

    目录 1.11g中表的类型: 2.高水位线HWM,(High Water Mark) 3.PCTFREE 和PCTUSED: 4. move.shrink.truncate来降低高水位线 5.IOT表 ...

  10. Oracle索引梳理系列(五)- Oracle索引种类之表簇索引(cluster index)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

最新文章

  1. dataTables常用参数
  2. [转载]全金属外壳——坦克遥控高射机枪
  3. 真人语音朗读软件_才知道,手机还自带文字转语音功能,一键按下便可实现,网友:赞...
  4. 通过system调用Am命令执行动作
  5. Android中Handler的使用方法——在子线程中更新界面
  6. Python利用Graphviz画图
  7. 电脑登录斗鱼显示无法连接服务器,斗鱼电脑版登录不了怎么办
  8. ExoPlayer之SampleQueue
  9. 《遥感原理与应用》第三版——思维导图
  10. python开发抢票软件_12306抢票软件run python版
  11. 中科院计算机技术研究所张浩,中国科学院计算技术研究所 韩 琥 博士
  12. malloc(): corrupted top size 解决
  13. beaglebone black下接nrf24l01与RFID标签的通信(基于EZSDK linux平台)
  14. sprintf()和itoa()的区别
  15. 数字图像处理---空间滤波基础
  16. es5 es6 互相转换
  17. 日期调用API,查询是否是节假日
  18. 如何部署Node项目到线上服务器?
  19. PLC的具体应用领域主要有哪些
  20. 提高效率和质量——生产车间6S管理

热门文章

  1. 我们在GDC上公布了一些好消息
  2. linux编译 __stdcall,Linux中是否有STDCALL?
  3. Spark 学习: spark 原理简述与 shuffle 过程介绍
  4. OA协同办公系统对企业建设会带来什么好处?
  5. Windows卓越性能概念以及如何打开
  6. WeightBiases教程
  7. FATAL :210330:1710: 3.0 SOLVE/read_biases: Zero WL biases read from N-file
  8. matplotlib读取png文件错误ValueError: invalid PNG header
  9. 浏览器扩展插件:「油猴」使用详解 ( Tampermonkey )
  10. 数据结构问题解决2.1——单链表存储结构定义详细解释,struct LNode* next解释,为啥next定义成指针类型