查看: 2399|回复: 6

[原创] 请优化高手来改写一下以下这条SQL

[复制链接]
论坛徽章:
7
ITPUB9周年纪念徽章
日期:2010-10-08 09:31:212011新春纪念徽章
日期:2011-02-18 11:43:34鲜花蛋
日期:2011-05-26 15:54:08ITPUB十周年纪念徽章
日期:2011-11-01 16:25:512012新春纪念徽章
日期:2012-01-04 11:56:44秀才
日期:2016-01-21 13:42:39射手座
日期:2016-03-04 16:38:02
发表于 2011-7-23 17:07 | 显示全部楼层 |阅读模式
select a.*
  from (select *
          from  test1         
         where
              dtime between
               to_date('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss') and
               to_date('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
           AND a1 = '02'
           and a2 = 'a80000') a
inner join (select c1, c2, c3, c4
               from  test1 a
              where
                 dtime  between
                    to_date('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss') and
                    to_date('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
                AND a1 = '02'
                and a2 = 'a80000'
                AND rowid > (SELECT  MIN(ROWID)
                               FROM  test1 b
                              where
                                dtime  between
                                    to_date('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss') and
                                    to_date('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
                                AND a1 = '02'
                                and a2 = 'a80000'
                                and a.c1 = b.c1                                
                                and a.c2 = b.c2
                                and a.c3 = b.c3
                                and a.c4 = b.c4)) b
    on a.c1 = b.c1   
    and a.c2 = b.c2
    and a.c3 = b.c3
    and a.c4 = b.c4;

请大家认真看一下
这是一个自身查询重复记录的SQL,请问如何改写这个SQL这个test1 表有5KW条
论坛徽章:
7
ITPUB9周年纪念徽章
日期:2010-10-08 09:31:212011新春纪念徽章
日期:2011-02-18 11:43:34鲜花蛋
日期:2011-05-26 15:54:08ITPUB十周年纪念徽章
日期:2011-11-01 16:25:512012新春纪念徽章
日期:2012-01-04 11:56:44秀才
日期:2016-01-21 13:42:39射手座
日期:2016-03-04 16:38:02
 楼主| 发表于 2011-7-23 17:50 | 显示全部楼层
我看这了这么久,我认为就是取 表test1 在列c1,c2,c3,c4上 的所有重复记录的所有列记录
上面这个SQL是不是这个意思,帮理解下

使用道具 举报

回复
论坛徽章:
15
2011新春纪念徽章
日期:2011-02-18 11:42:47马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02夏利
日期:2014-01-05 23:30:122013年新春福章
日期:2013-02-25 14:51:24咸鸭蛋
日期:2013-01-06 18:38:44复活蛋
日期:2012-12-27 22:39:382012新春纪念徽章
日期:2012-01-04 11:51:22ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15蛋疼蛋
日期:2011-08-03 23:04:21
发表于 2011-7-24 11:53 | 显示全部楼层
select * from test1 where (c1,c2,c3,c4) in
select c1,c2,c3,c4 from test1
where dtime  between
                                    to_date('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss') and
                                    to_date('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
           AND a1 = '02'
           and a2 = 'a80000'
group by c1,c2,c3,c4 having count(1)>1

使用道具 举报

回复
论坛徽章:
10000
地主之星
日期:2015-07-20 17:15:36地主之星
日期:2015-09-01 14:14:25地主之星
日期:2015-09-01 17:59:09地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58地主之星
日期:2015-08-31 16:17:58
发表于 2011-7-24 12:33 | 显示全部楼层
原帖由 mkstone 于 2011-7-24 11:53 发表
select * from test1 where (c1,c2,c3,c4) in
select c1,c2,c3,c4 from test1
where dtime  between
                                    to_date('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss') and
                                    to_date('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
           AND a1 = '02'
           and a2 = 'a80000'
group by c1,c2,c3,c4 having count(1)>1

使用道具 举报

回复
论坛徽章:
5
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51数据库板块每日发贴之星
日期:2011-07-22 01:01:02蜘蛛蛋
日期:2011-08-24 14:10:13ITPUB十周年纪念徽章
日期:2011-11-01 16:24:042012新春纪念徽章
日期:2012-01-04 11:54:26
发表于 2011-7-24 22:46 | 显示全部楼层
要优化SQL 好看执行计划!!!  
有时候 不用改写SQL,有时候需要改写SQL,关键就是 让CBO能选择一个最佳的访问路径

使用道具 举报

回复
论坛徽章:
14
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:52沸羊羊
日期:2015-03-04 14:43:43马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11福特
日期:2013-10-14 21:18:25凯迪拉克
日期:2013-09-23 23:01:572013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412011新春纪念徽章
日期:2011-02-18 11:43:33
发表于 2011-7-25 09:21 | 显示全部楼层
最外層的a和b 做join似乎已經沒必要

/* Formatted on 2011/07/25 09:16 (Formatter Plus v4.8.8) */
SELECT *
  FROM test1 a
WHERE dtime BETWEEN TO_DATE ('2011-05-23 20:00:00', 'yyyy-mm-dd hh24:mi:ss')
                 AND TO_DATE ('2011-05-24 08:00:00', 'yyyy-mm-dd hh24:mi:ss')
   AND a1 = '02'
   AND a2 = 'a80000'
   AND ROWID >
          (SELECT MIN (ROWID)
             FROM test1 b
            WHERE dtime BETWEEN TO_DATE ('2011-05-23 20:00:00',
                                         'yyyy-mm-dd hh24:mi:ss'
                                        )
                            AND TO_DATE ('2011-05-24 08:00:00',
                                         'yyyy-mm-dd hh24:mi:ss'
                                        )
              AND a1 = '02'
              AND a2 = 'a80000'
              AND a.c1 = b.c1
              AND a.c2 = b.c2
              AND a.c3 = b.c3
              AND a.c4 = b.c4);

這個改寫SQL看看結果一致不

這個SQL寫的很怪,為什麼要用MIN (ROWID)可能要仔細問問開發

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
0
发表于 2014-3-17 22:51 | 显示全部楼层
已结贴:

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表