12
返回列表 发新帖
楼主: ljljlj168

一条SQL的优化问题请教版主?

[复制链接]
论坛徽章:
168
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-01-04 11:49:54蜘蛛蛋
日期:2011-12-05 16:08:56ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41设计板块每日发贴之星
日期:2011-07-22 01:01:02ITPUB官方微博粉丝徽章
日期:2011-06-30 12:30:16管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:33
11#
发表于 2005-3-15 19:00 | 只看该作者
还是把执行计划贴出来看看把....

使用道具 举报

回复
论坛徽章:
0
12#
发表于 2005-3-15 20:42 | 只看该作者
select count(userid) from order
where ifsend = 1
and substr(sendid,1,2) = 'EC'
and asst_id in (904,4553,4874)
and userid in (select userid from order
where ifsend = 1 and asst_id = 0 and substr(sendid,1,2) not in ('EQ','TB','EP'));
===================================
在sendid上建索引,然后将substr(sendid,1,2)='EC'改成sendid like 'EC%'应该会更好些。

使用道具 举报

回复
论坛徽章:
0
13#
 楼主| 发表于 2005-3-16 09:39 | 只看该作者
没加DISTINCT的:
Plan Table
--------------------------------------------------------------------------------
| Operation                  |  Name    |  Rows | Bytes|  Cost  |  TQ  |IN-OUT|
PQ Distrib | Pstart| Pstop |

--------------------------------------------------------------------------------
----------------------------

| SELECT STATEMENT           |          |     1 |   21 |     10 |      |      |
           |       |       |

|  SORT AGGREGATE            |          |     1 |   21 |        |      |      |
           |       |       |

Plan Table
--------------------------------------------------------------------------------

|   FILTER                   |          |       |      |        |      |      |
           |       |       |

|    TABLE ACCESS BY INDEX RO|EC_ORDER_ |     1 |   21 |     10 |      |      |
           |       |       |

|     INDEX RANGE SCAN       |ASST_INDE |     1 |      |      1 |      |      |
           |       |       |

|    TABLE ACCESS BY INDEX RO|EC_ORDER_ |     1 |   21 |      6 |      |      |

Plan Table
--------------------------------------------------------------------------------
           |       |       |

|     AND-EQUAL              |          |       |      |        |      |      |
           |       |       |

|      INDEX RANGE SCAN      |ASST_INDE |     1 |      |      1 |      |      |
           |       |       |

|      INDEX RANGE SCAN      |EC_ORDER_ |     1 |      |      1 |      |      |
           |       |       |


加DISTINCT的:
Plan Table
--------------------------------------------------------------------------------
| Operation                  |  Name    |  Rows | Bytes|  Cost  |  TQ  |IN-OUT|
PQ Distrib | Pstart| Pstop |

--------------------------------------------------------------------------------
----------------------------

| SELECT STATEMENT           |          |     1 |   42 |     12 |      |      |
           |       |       |

|  SORT GROUP BY             |          |     1 |   42 |        |      |      |
           |       |       |

Plan Table
--------------------------------------------------------------------------------

|   NESTED LOOPS             |          |     1 |   42 |     12 |      |      |
           |       |       |

|    TABLE ACCESS BY INDEX RO|EC_ORDER_ |     1 |   21 |     10 |      |      |
           |       |       |

|     INDEX RANGE SCAN       |ASST_INDE |     1 |      |      1 |      |      |
           |       |       |

|    TABLE ACCESS BY INDEX RO|EC_ORDER_ |     1 |   21 |      2 |      |      |

Plan Table
--------------------------------------------------------------------------------
           |       |       |

|     INDEX RANGE SCAN       |EC_ORDER_ |     1 |      |      1 |      |      |
           |       |       |

谢谢

使用道具 举报

回复
论坛徽章:
0
14#
 楼主| 发表于 2005-3-16 09:41 | 只看该作者
句子:
select count(userid) from ec_order_mainorder a
where ifsend = 1
and  sendid like 'EC%'
and  asst_id = 1453
and exists (select userid from ec_order_mainorder b
              where ifsend = 1
              and asst_id = 0
              and a.userid = b.userid
              and substr(sendid,1,2) not in ('EQ','TB','EP'));

select count(distinct userid) from ec_order_mainorder a
where ifsend = 1
and  sendid like 'EC%'
and  asst_id = 1453
and exists (select userid from ec_order_mainorder b
              where ifsend = 1
              and asst_id = 0
              and a.userid = b.userid
              and substr(sendid,1,2) not in ('EQ','TB','EP'));

使用道具 举报

回复
论坛徽章:
0
15#
 楼主| 发表于 2005-3-16 09:56 | 只看该作者
没加DISTINCT的:
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=28 Card=1 Bytes=21)
   1    0   SORT (AGGREGATE)
   2    1     FILTER
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'EC_ORDER_MAINORDER'
          (Cost=28 Card=1 Bytes=21)

   4    3         INDEX (RANGE SCAN) OF 'SENDID_UNIQUE' (UNIQUE) (Cost
          =3 Card=1)

   5    2       TABLE ACCESS (BY INDEX ROWID) OF 'EC_ORDER_MAINORDER'
          (Cost=17 Card=1 Bytes=21)

   6    5         AND-EQUAL
   7    6           INDEX (RANGE SCAN) OF 'EC_ORDER_MAINORDER_IDX_USER
          ID' (NON-UNIQUE) (Cost=3 Card=1)

   8    6           INDEX (RANGE SCAN) OF 'EC_ORDER_MAINORDER_ASSTID_I
          DX' (NON-UNIQUE) (Cost=10 Card=1)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
     199018  consistent gets
       1117  physical reads
          0  redo size
        373  bytes sent via SQL*Net to client
        425  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          1  rows processed

加DISTINCT的:
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=31 Card=1 Bytes=42)
   1    0   SORT (GROUP BY)
   2    1     NESTED LOOPS (Cost=31 Card=1 Bytes=42)
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'EC_ORDER_MAINORDER'
          (Cost=28 Card=1 Bytes=21)

   4    3         INDEX (RANGE SCAN) OF 'SENDID_UNIQUE' (UNIQUE) (Cost
          =3 Card=1)

   5    2       TABLE ACCESS (BY INDEX ROWID) OF 'EC_ORDER_MAINORDER'
          (Cost=3 Card=1 Bytes=21)

   6    5         INDEX (RANGE SCAN) OF 'EC_ORDER_MAINORDER_IDX_USERID
          ' (NON-UNIQUE) (Cost=2 Card=1)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
    8862914  consistent gets
        926  physical reads
          0  redo size
        381  bytes sent via SQL*Net to client
        425  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

使用道具 举报

回复
论坛徽章:
168
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-01-04 11:49:54蜘蛛蛋
日期:2011-12-05 16:08:56ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41设计板块每日发贴之星
日期:2011-07-22 01:01:02ITPUB官方微博粉丝徽章
日期:2011-06-30 12:30:16管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:33
16#
发表于 2005-3-16 11:55 | 只看该作者
换成下面的写法试试?

1.
select count(distinct userid) from
(
select userid
from ec_order_mainorder a
where ifsend = 1
and sendid like 'EC%'
and asst_id = 1453
and exists (select userid from ec_order_mainorder b
  where ifsend = 1
  and asst_id = 0
  and a.userid = b.userid
  and substr(sendid,1,2) not in ('EQ','TB','EP')
  )
);

2.
select count(distinct userid) from ec_order_mainorder a
where ifsend = 1
and sendid like 'EC%'
and asst_id = 1453
and userid in (select /*+hash_sj*/ userid from ec_order_mainorder b
where ifsend = 1
and asst_id = 0
and substr(sendid,1,2) not in ('EQ','TB','EP')
);

使用道具 举报

回复
论坛徽章:
0
17#
 楼主| 发表于 2005-3-16 12:31 | 只看该作者
谢谢

使用道具 举报

回复
论坛徽章:
168
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-01-04 11:49:54蜘蛛蛋
日期:2011-12-05 16:08:56ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41设计板块每日发贴之星
日期:2011-07-22 01:01:02ITPUB官方微博粉丝徽章
日期:2011-06-30 12:30:16管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:33
18#
发表于 2005-3-16 12:51 | 只看该作者
最初由 ljljlj168 发布
[B]谢谢 [/B]


可能的话把表的数据大小,列上的索引情况再说明一下?
btw:
最好把调优结果贴出来看看.

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
38
ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14现任管理团队成员
日期:2012-10-18 17:11:21版主4段
日期:2012-05-15 15:24:112012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
19#
发表于 2005-3-16 13:24 | 只看该作者
就算慢也不至于执行不出来吧。
不排序的就可以,是不是临时表空间满了之类的其它原因导致的?这个表有多少行?查询的结果分别是多少行呢?也讲讲吧

使用道具 举报

回复
论坛徽章:
0
20#
 楼主| 发表于 2005-3-16 16:44 | 只看该作者
开始的确跑不出来
后来改了改可以了

使用道具 举报

回复

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

本版积分规则 发表回复

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