楼主: 〇〇

[转载] 108-一个SQL, 两种优化方法, 效果都还可以

[复制链接]
论坛徽章:
2
20周年集字徽章-周
日期:2023-08-03 16:37:4519周年集字徽章-19
日期:2024-09-07 21:32:18
11#
发表于 2023-8-14 22:56 | 只看该作者
本帖最后由 sql_tigerliu 于 2023-8-14 23:00 编辑
newkid 发表于 2023-8-14 22:02
我把标量子查询换了一个索引列,简化了一下,效果也不错,都是1.X秒:create index idx_T_DEMO_648_Wind_W_ ...

苏老师, 你这个写法我测试执行耗时130秒, 我不知道你的1.x秒是什么来的. 这个写法的最大问题是, 如果给一个较大的h.beg_date, 它要从索引的最小值开始匹配, 然后发现不满足<w.end_date被丢弃,  h.beg_date传入的值越大, 执行的越慢.  这种区间检索的问题, 我研究的比较多, 我那种两层的写法的效率还是比较高的. 如果用beg_date, 要用降序扫描才行(你的写法加index_desc hint,  耗时1.22秒).  你这种一层的写法, 如果遇到匹配不到的情况, 耗时也会增加, 如果能确保都匹配到, 也可以这样写, 用beg_data就要降序, 用end_date就不需要降序.

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
12#
发表于 2023-8-14 22:57 | 只看该作者
如果要让 beg_date 上的索引起作用,就得让它降序:
create index idx_T_DEMO_648_Wind_W_2 on T_DEMO_648_Wind_W(i_code,beg_date desc);

这样的话九楼的写法就能奏效了。

使用道具 举报

回复
论坛徽章:
2
20周年集字徽章-周
日期:2023-08-03 16:37:4519周年集字徽章-19
日期:2024-09-07 21:32:18
13#
发表于 2023-8-14 23:04 | 只看该作者
newkid 发表于 2023-8-14 22:57
如果要让 beg_date 上的索引起作用,就得让它降序:create index idx_T_DEMO_648_Wind_W_2 on T_DEMO_648_W ...

https://mp.weixin.qq.com/s/oRcLfXKz2k-pCrTV7f9Aww

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
14#
 楼主| 发表于 2023-8-14 23:10 来自手机 | 只看该作者
duckdb运行newkid的写法也是9秒,看来它不能用这种优化

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
15#
发表于 2023-8-14 23:56 | 只看该作者
sql_tigerliu 发表于 2023-8-14 22:56
苏老师, 你这个写法我测试执行耗时130秒, 我不知道你的1.x秒是什么来的. 这个写法的最大问题是, 如果给一个 ...

我刚才发帖的时候你的回帖还没显示出来,我也确实发现beg_date要降序才可以,这是由区间匹配的天然属性所决定的。我试图用新语法 order by W.beg_date desc FETCH NEXT 1 ROW ONLY 来实现只写一层,但是这个新语法还是很慢。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
16#
发表于 2023-8-14 23:57 | 只看该作者
〇〇 发表于 2023-8-14 23:10
duckdb运行newkid的写法也是9秒,看来它不能用这种优化

像我12楼那样把索引建成降序的,会怎么样?

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
17#
 楼主| 发表于 2023-8-15 05:54 | 只看该作者


还是一样,它的执行计划没有用到索引

使用道具 举报

回复
论坛徽章:
2
20周年集字徽章-周
日期:2023-08-03 16:37:4519周年集字徽章-19
日期:2024-09-07 21:32:18
18#
发表于 2023-8-15 09:07 | 只看该作者
newkid 发表于 2023-8-14 23:56
我刚才发帖的时候你的回帖还没显示出来,我也确实发现beg_date要降序才可以,这是由区间匹配的天然属性所决 ...

12c的offset  fetch写法, 内部是用row_number分析实现的, 把标量子查询部分单独拿出来执行, 执行计划可以走"WINDOW NOSORT STOPKEY",这个效率是可以的; 但是在标量子查询里面, 执行计划就变成了"WINDOW BUFFER PUSHED RANK", 这个效率是较差的. 即使使用这种写法, 也是要两层, 才能解决匹配不到时效率差的问题.  这个案例返回的是一个字段, 如果返回的是多个字段, 我还尝试过outer apply的写法, 也是无法实现标量子查询写法的效率.

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
19#
 楼主| 发表于 2023-8-15 11:18 来自手机 | 只看该作者
不知下面写法是否等价

select h.*,w.dp_close as w_dp_close
from   H
LEFT JOIN  W
     ON   H.I_CODE = W.I_CODE
      AND W.BEG_DATE <= H.BEG_DATE
      AND W.END_DATE >=  H.END_DATE;

使用道具 举报

回复
论坛徽章:
18
优秀写手
日期:2014-02-27 06:00:13秀才
日期:2017-12-12 09:52:44秀才
日期:2017-08-11 15:37:32弗兰奇
日期:2017-07-04 09:16:01秀才
日期:2017-06-29 10:16:48乌索普
日期:2017-05-26 08:58:24娜美
日期:2017-05-18 16:07:23ITPUB15周年纪念
日期:2017-05-02 15:22:36妮可·罗宾
日期:2017-04-06 10:06:19处女座
日期:2016-03-10 09:03:26
20#
发表于 2023-8-15 13:53 | 只看该作者
拉链表不适合百万级以上的。 如果一个表到了百万级了还是冗余成日频表更好用,分区、索引都方便

使用道具 举报

回复

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

本版积分规则 发表回复

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