查看: 734|回复: 16

可否优化

[复制链接]
论坛徽章:
0
发表于 2018-1-9 21:46 | 显示全部楼层 |阅读模式
分页语句
select * from (
       select t.rownum rn,t.* from
                 (select b.column_name,a.owner,a.object_type,a.last_ddl_time
                            from  t_objects a
                          left join t_columns b on a.object_id=b.object_id
                          order by last_ddl_time)
                where rownum<100)
        and rn>80;

  t_objects,t_columns 两表各有记录约 十万条, 走HASH JOIN,大家觉得上面的语句有优化的空间吗?
如果有,能否拿出 证据?谢谢!
认证徽章
论坛徽章:
0
发表于 2018-1-9 21:58 | 显示全部楼层
1. 把SQL相关表和索引,数据行数和分布,执行计划贴出来。大家可以帮你出出主意;
2. 或者下载一个免费的优化工具,自己搞定。
     下载地址: https://tosska.com/tosska-sql-tu ... acle-free-download/
      旧帖: http://www.itpub.net/thread-2095752-1-1.html
   

使用道具 举报

回复
论坛徽章:
0
 楼主| 发表于 2018-1-9 22:29 | 显示全部楼层
create table t_objects as select * from dba_objects;
create table t_columns as select owner,table_name,column_name,data_type,DATA_TYPE_OWNER,COLUMN_ID,NUM_DISTINCT,LOW_VALUE,HIGH_VALUE,DENSITY from dba_tab_columns;

select * from (
       select t.*,rownum as rn from
                 (select b.column_name,a.owner,a.object_type,a.last_ddl_time
                            from  t_objects a
                          left join t_columns b on a.owner=b.owner
                              and a.object_name=b.table_name
                          order by last_ddl_time desc) t
                where rownum<100)
        where rn>80;

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  6ckkb29n58vf2, child number 0
-------------------------------------
select * from (        select t.*,rownum as rn from           (select
b.column_name,a.owner,a.object_type,a.last_ddl_time        from
t_objects a      left join t_columns b on a.owner=b.owner          and
a.object_name=b.table_name      order by last_ddl_time desc) t   where
rownum<100)  where rn>80

Plan hash value: 3439119502

-------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |           |      1 |        |     19 |00:00:00.42 |    1750 |   1744 |       |       |          |
|*  1 |  VIEW                     |           |      1 |     99 |     19 |00:00:00.42 |    1750 |   1744 |       |       |          |
|*  2 |   COUNT STOPKEY           |           |      1 |        |     99 |00:00:00.42 |    1750 |   1744 |       |       |          |
|   3 |    VIEW                   |           |      1 |  63457 |     99 |00:00:00.42 |    1750 |   1744 |       |       |          |
|*  4 |     SORT ORDER BY STOPKEY |           |      1 |  63457 |     99 |00:00:00.42 |    1750 |   1744 | 40960 | 40960 |36864  (0)|
|*  5 |      HASH JOIN RIGHT OUTER|           |      1 |  63457 |    155K|00:00:00.37 |    1750 |   1744 |  6704K|  2359K|   10M (0)|
|   6 |       TABLE ACCESS FULL   | T_COLUMNS |      1 |  78904 |  89204 |00:00:00.17 |     719 |    716 |       |       |          |
|   7 |       TABLE ACCESS FULL   | T_OBJECTS |      1 |  63457 |  72171 |00:00:00.02 |    1031 |   1028 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("RN">80)
   2 - filter(ROWNUM<100)
   4 - filter(ROWNUM<100)
   5 - access("A"."OBJECT_NAME"="B"."TABLE_NAME" AND "A"."OWNER"="B"."OWNER")

Note
-----
   - dynamic sampling used for this statement (level=2)


35 rows selected.

使用道具 举报

回复
论坛徽章:
310
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
发表于 2018-1-9 22:52 | 显示全部楼层
是否存在主外键关系?

对 LAST_DDL_time 建个索引试试,

使用道具 举报

回复
论坛徽章:
188
红宝石
日期:2014-05-09 08:24:37萤石
日期:2014-01-03 10:25:39奥运会纪念徽章:羽毛球
日期:2008-07-01 10:46:06奥运会纪念徽章:马术
日期:2008-07-07 17:43:24奥运会纪念徽章:射箭
日期:2008-07-25 18:07:39奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-30 10:02:57奥运会纪念徽章:花样游泳
日期:2008-09-26 13:02:43奥运会纪念徽章:排球
日期:2008-12-03 11:23:272010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:澳大利亚
日期:2010-02-26 11:08:44
发表于 2018-1-10 08:37 | 显示全部楼层
这种优化要规避回表。也就是建立一个大索引来优化。

使用道具 举报

回复
论坛徽章:
74
ITPUB18周年纪念章
日期:2018-09-17 10:09:49双子座
日期:2016-01-19 20:35:54秀才
日期:2016-01-13 12:14:26秀才
日期:2015-12-25 15:31:10秀才
日期:2015-12-18 09:28:57秀才
日期:2015-12-14 14:56:09秀才
日期:2015-12-14 14:51:16秀才
日期:2015-11-30 09:13:06处女座
日期:2015-11-27 12:27:01秀才
日期:2015-11-23 10:17:19
发表于 2018-1-10 09:50 | 显示全部楼层
用SQL做分页永远是浪费计算资源。变化不大直接做宽表算了

使用道具 举报

回复
认证徽章
论坛徽章:
0
发表于 2018-1-10 11:53 | 显示全部楼层
黄山情缘99 发表于 2018-1-9 22:29
create table t_objects as select * from dba_objects;
create table t_columns as select owner,table_n ...

1. 建索引 create index idx_t_columns_owner_tab_name on t_columns(owner, table_name);

2. 重写一下:
SELECT *
FROM   (SELECT *
        FROM   (SELECT c.*, rownum rn
                FROM   (SELECT owner,object_name,
                               object_type,
                               last_ddl_time
                        FROM   t_objects
                        ORDER  BY last_ddl_time DESC) c
                WHERE  ROWNUM < 100) a
               left join t_columns b
                      ON a.owner = b.owner
                         AND a.object_name = b.table_name)
WHERE  rn > 80

使用道具 举报

回复
论坛徽章:
0
 楼主| 发表于 2018-1-10 22:14 | 显示全部楼层
正确的方法是建索引ast_ddl_time,owner,object_name,谁能解释一下?

使用道具 举报

回复
论坛徽章:
310
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
发表于 2018-1-10 23:06 | 显示全部楼层
黄山情缘99 发表于 2018-1-10 22:14
正确的方法是建索引ast_ddl_time,owner,object_name,谁能解释一下?

贴出出实际的运行结果,若语句加了提示,  gather_plan_statistics 后再执行, 执行结束后获取到的执行过程
那更好,

使用道具 举报

回复
认证徽章
论坛徽章:
8
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:07:24ITPUB9周年纪念徽章
日期:2010-10-08 09:32:25ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262013年新春福章
日期:2013-02-25 14:51:24沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:57:31
发表于 2018-1-11 16:07 | 显示全部楼层
本帖最后由 sqysl 于 2018-1-11 16:14 编辑
黄山情缘99 发表于 2018-1-9 22:29
create table t_objects as select * from dba_objects;
create table t_columns as select owner,table_n ...

1、这样的话,两张表不可能数据一样多,t_columns应该比t_objects多不少;
2、create index i1_t_objects in t_objects(last_ddl_time,owner,object_name,object_type),这样,可以做到一箭三雕(再具体自己想,有些版本也许需要hint搞定);如果加上create index i1_t_columns on t_columns(owner,table_name,column_name)也许就更好了。

使用道具 举报

回复

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

本版积分规则 发表回复

第67期:Neo4j图数据库平台架构最佳实践
【微学堂】10月18日 20:00(周四)

当下,数据的规模和类型每时每刻都在呈几何级数的增长,仅能够管理大量的数据是不够的,关键是能从海量数据中发掘出有用的信息,特别是数据之间的关联,能高效存储和处理数据之间关联的新型数据库为图数据库。 本讲座将介绍Neo4j图数据库的基本概念、设计特点、架构和经典应用场景实战分享。

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