楼主: rollingpig

[精华] 分享一下SQL数据库编程大赛第一期我的解法

[复制链接]
论坛徽章:
131
2006年度最佳技术回答
日期:2007-01-24 12:58:48福特
日期:2013-10-24 13:57:422014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:142013年新春福章
日期:2013-02-25 14:51:24
11#
 楼主| 发表于 2011-3-29 12:41 | 只看该作者
其实,我想过更进一步,就是把5*5扩展成M*M, 但是,我很悲剧的发现,在当前给定条件下,就算是简单的M=6,N=2, 就算是用上probe也是以分钟计,更别说6/3, 7/2之类的。
所以,放弃了进一步扩展的想法。

巧的是,评委们也觉得扩展成M*M将会很有意思,于是,在用"等于号"限定了球数之后,作为第二期题目了……

使用道具 举报

回复
论坛徽章:
2
SQL大赛参与纪念
日期:2011-04-13 12:08:17奥运会纪念徽章:排球
日期:2012-10-08 20:49:04
12#
发表于 2011-3-29 13:51 | 只看该作者
楼主利害啊,我先记号一下,慢慢看

使用道具 举报

回复
论坛徽章:
2
SQL大赛参与纪念
日期:2011-04-13 12:08:17奥运会纪念徽章:排球
日期:2012-10-08 20:49:04
13#
发表于 2011-3-29 13:52 | 只看该作者
楼主可否把后面几期的思路也分析一下?

使用道具 举报

回复
论坛徽章:
548
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:222012新春纪念徽章
日期:2020-11-30 22:13:24海蓝宝石
日期:2012-02-20 19:24:27
14#
发表于 2011-3-29 14:17 | 只看该作者
好人,谢谢分享,慢慢品读。。。

使用道具 举报

回复
论坛徽章:
10000
绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2015-12-16 18:42:35绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-09-10 13:05:08
15#
发表于 2011-3-29 14:25 | 只看该作者
牛人

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
16#
发表于 2011-3-29 17:27 | 只看该作者


我在 http://www.itpub.net/thread-1407072-1-1.html
对楼主一期答案的评价
评析:构思巧妙,采用由浅入深的做法,先用probed_result探测出可以放置的球最少是多少,当然,作者期望这个值越大越好,所以在之前probed_result要调用的linesrc查询中,作者特意做了一个从大到小的倒排序(ORDER BY 1 desc),以期能从中尽早尽快的获得可能的最大的球数。然而这个代码并非就是那么完美,一旦probed_max_balls-4*:N<=0,则probed_result查询所做的工作就等于打水漂了,即便probed_max_balls-4*:N=1也占不了0.01%的便宜,rownum < power(16,:N)的条件并不科学,不过从认为此值应该是一个“不小的较合适的数”去看,则可算合理。最后的solution查询没有使用前面得到的probed_max_balls来产生一个新的制约条件也是一个遗憾。不管怎样,“浅入虎穴”的思路是不错的,值得我们学习。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
17#
发表于 2011-3-29 17:32 | 只看该作者
原帖由 rollingpig 于 11-3-29 12:36 发表
如果能用上=:N的条件,性能将会提高数百倍。       

直接用,没那个胆,毕竟“正确性和完善程度”是很重要的,在题目内容中及有限的推理过程中,并不能得出 =:N的条件。可是,如果有一种方法,在SQL的内部就直接证明,的确存在5*N的摆法,那么,就可以理直气壮的使用上=:N的条件了。

这时候,灵感突然来了,如果我在SQL里嵌入一段,在求solution结果的运算变的很慢之前,就发现有存在5*N的摆法,不就解决了吗?
用rownum 来限制,应该可以在性能变糟之前就得到吧?

Tips: 特定的时候,使用rownum限定结果集,有助于提高性能,但是仅限于“只获取部分数据”
………………


经过尝试,发现N=2时,N*5出现在199, N=3,发生在1916, N=4发生在 17638。
而如果用了where rownum < :max_rows, 性能非常的好。
这时候,又有一个问题,怎么把这个:max_rows里写进去了,有两个写法,一是直接取最大,大家都按N=4的时候的50000来算,但是,就是当N=2/3是有点亏。
最后选择了Power(16,:N), 正好都cover. (其实 2*power(10,:N) 更合适).

  


最后部分既是亮点也是弱点,正如你现在自己说的“(其实 2*power(10,:N) 更合适)”
这个值合适不合适,到底取多少合适?其实是有点从答案倒推过程了

使用道具 举报

回复
论坛徽章:
131
2006年度最佳技术回答
日期:2007-01-24 12:58:48福特
日期:2013-10-24 13:57:422014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:142013年新春福章
日期:2013-02-25 14:51:24
18#
 楼主| 发表于 2011-3-29 20:09 | 只看该作者
我也想给这个数据找一个现实意义,比如说,总数据量的千分之一之类的,但是那又更复杂了。
原帖由 lastwinner 于 2011-3-29 17:32 发表


最后部分既是亮点也是弱点,正如你现在自己说的“(其实 2*power(10,:N) 更合适)”
这个值合适不合适,到底取多少合适?其实是有点从答案倒推过程了

使用道具 举报

回复
论坛徽章:
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
19#
发表于 2011-3-29 21:51 | 只看该作者
原帖由 lastwinner 于 2011-3-29 17:32 发表


最后部分既是亮点也是弱点,正如你现在自己说的“(其实 2*power(10,:N) 更合适)”
这个值合适不合适,到底取多少合适?其实是有点从答案倒推过程了


确实,如果不是这个“倒推”法就更完美了。SQL和过程线代码不同,一般都是穷尽的思路,非穷尽的情况下要按最悲观的情形来做假设。

使用道具 举报

回复
论坛徽章:
131
2006年度最佳技术回答
日期:2007-01-24 12:58:48福特
日期:2013-10-24 13:57:422014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:142013年新春福章
日期:2013-02-25 14:51:24
20#
 楼主| 发表于 2011-3-30 10:47 | 只看该作者
穷尽就失去了性能的优势。
还有就是用找出first 5*N的行,但是,那也相当于预先推测存在5*N的行。

另外,从逻辑上来说,妙的是,我最后用的条件是

Balls >= max_ball - :N*4 and ball <=:N


并没有要求max_ball 一定就等于5*N, 在 max_ball =5*N-1(比如说是,N=4时,max_balls=19),同样能获得正确结果和很好的性能。

也就是说,不需要“穷尽”,假设我把power(2,:N)改成10000,2000 在N=3,4时同样能够获得很好的性能(这时候,max_balls=19, 运行4 seconds)。
就算我把power(2,:N)改为100, 只是max_ball 取得一个很差的值,结果也并不受影响,只是性能没有获得提升。

就像Oracle在执行SQL时有时候有的dynantic sampling的做法,这个sample 该是多少,也仅仅是Oracle设计的时的一个经验值。




原帖由 newkid 于 2011-3-29 21:51 发表


确实,如果不是这个“倒推”法就更完美了。SQL和过程线代码不同,一般都是穷尽的思路,非穷尽的情况下要按最悲观的情形来做假设。

使用道具 举报

回复

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

本版积分规则 发表回复

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