这个sql语句好怪,请高手指点

zlxzm 2005-10-14 02:02:47
请教一个sql语句的问题_20051014

fw_khhfdb表1192132条记录,主键是djid,另外,对fwdwid字段建有一个索引,对hfrq 字段也建立了一个索引,在toad中执行以下语句:

SELECT COUNT (*)
FROM fw_khhfdb
WHERE fwdwid =559
AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')

很快得到结果:12548

但是执行以下各语句时,费时很久,跟死机一样:

SELECT COUNT (*)
FROM fw_khhfdb
WHERE (fwdwid =559 or fwdwid = 1119)
AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')

或者:

SELECT COUNT (*)
FROM fw_khhfdb
WHERE hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
AND (fwdwid =559 or fwdwid = 1119)

或者:

SELECT COUNT (*)
FROM fw_khhfdb
WHERE HFFS = 1
AND fwdwid =559
AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')

其中,HFFS 是一个只有0、1两个值的字段,未单独建有索引。

请帮我分析一下,多谢!
...全文
865 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
boydgmx 2005-12-21
  • 打赏
  • 举报
回复
建议分析一下数据表和索引,很可能是 fwdwid 这个索引需要重建了
hlp912 2005-11-19
  • 打赏
  • 举报
回复
因为你的第一种写法是最优的

ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.

RedFire 2005-11-10
  • 打赏
  • 举报
回复
重建一个索引试试。
tangtangno1 2005-10-17
  • 打赏
  • 举报
回复
建立(hfrq,fwdwid)的复合索引
bobfang 2005-10-17
  • 打赏
  • 举报
回复
“另有一个类似表,数据300多万,也用类似的语句去查询,索引也一样,而用or的和不用Or的速度一样,都是一点就出结果,可不可能是表本身的问题,或者是数据库的问题?”,那么执行这两个查询的执行计划是相同的吗?如果不同,可以考虑对表做分析。
SInoyew 2005-10-17
  • 打赏
  • 举报
回复
学习。。
zlxzm 2005-10-17
  • 打赏
  • 举报
回复
另有一个类似表,数据300多万,也用类似的语句去查询,索引也一样,而用or的和不用Or的速度一样,都是一点就出结果,可不可能是表本身的问题,或者是数据库的问题?
qiaozhiwei 2005-10-15
  • 打赏
  • 举报
回复
不是吧,好像是or的速度要快点吧
zealot_zk 2005-10-14
  • 打赏
  • 举报
回复
注意一下你两个语句使用索引的顺序不同,是导致你两条语句执行效率差距很大的原因。在书写sql语句是应该尽量避免使用or条件,而使用in或者集合操作会提高sql语句的执行速度。
leborety 2005-10-14
  • 打赏
  • 举报
回复
试下这个:
SELECT COUNT (*)
FROM fw_khhfdb
WHERE hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
AND fwdwid = 1119

union
SELECT COUNT (*)
FROM fw_khhfdb
WHERE hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
AND fwdwid =559


这个和你上面的不是一个意思啊
SELECT COUNT (*)
FROM fw_khhfdb
WHERE HFFS = 1
AND fwdwid =559
AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd')
AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')

其中,HFFS 是一个只有0、1两个值的字段,未单独建有索引。

zlxzm 2005-10-14
  • 打赏
  • 举报
回复
第一个语句的执行计划:
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop

SELECT STATEMENT Optimizer Mode=CHOOSE 1 31
SORT AGGREGATE 1 12
VIEW FWGL.index$_join$_001 7 84 31
HASH JOIN 7 84
INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_FWDWID 7 84 39.00002622
INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_HFRQ 7 84 39.00002622

第二个语句的执行计划:
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop

SELECT STATEMENT Optimizer Mode=CHOOSE 1 13
SORT AGGREGATE 1 12
VIEW FWGL.index$_join$_001 13 156 13
HASH JOIN 13 156
INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_HFRQ 13 156 54.25002254
INLIST ITERATOR
INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_FWDWID 13 156 54.25002254
我不太明白,请帮我分析一下
bzszp 2005-10-14
  • 打赏
  • 举报
回复
分别看一下执行计划,比较一下有什么区别

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧