楼主: anlinew

sql 执行计划问题

[复制链接]
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
11#
 楼主| 发表于 2010-6-12 13:55 | 只看该作者
public class test_sybase_outjoin extends DMOBase {
        public static void main(String[] args) {
                query_stmt();
                query_pstmt();               
        }
       
        public static void query_stmt() {
                String selSql = "select *  from bd_psnbasdoc a left join bd_psndoc b on a.pk_psnbasdoc=b.pk_psnbasdoc where b.pk_psndoc = '1002PSN2100001000001'";
                Connection conn = null;
                Statement stmt = null;
                ResultSet rs = null;
               
                try {
                        conn = getConnection();
                        stmt = conn.createStatement();
                        long t_on_sql = System.currentTimeMillis();
                        stmt.executeQuery(selSql);
                        System.out.println("Statement 执行 耗时: " + (System.currentTimeMillis() - t_on_sql)); // 88888888888888                       
                } catch (Exception e) {
                        e.printStackTrace();
                }
               
        }

        public static void query_pstmt() {
                Connection conn = null;
                PreparedStatement stmt = null;
                String updSql = "select *  from bd_psnbasdoc a left join bd_psndoc b on a.pk_psnbasdoc=b.pk_psnbasdoc where b.pk_psndoc= ?";
                try {
                        conn = getConnection();
                        conn.setAutoCommit(false);
                        stmt = conn.prepareStatement(updSql);
                        long t_on_sql = System.currentTimeMillis();
                                stmt.setString(1, "1002PSN2100001000001");                               
                        stmt.execute();                       
                        System.out.println("prepareStatement 执行 耗时: " + (System.currentTimeMillis() - t_on_sql)); // 88888888888888
                        conn.commit();
                } catch (Exception E) {
                        E.printStackTrace();                       
                } finally {
                        closeDBResources(stmt, conn);
                }
        }
}



输出结果,时间单位: ms

Statement 执行 耗时: 47
prepareStatement 执行 耗时: 158646

这还只是百万级别的表,千万级的表玩儿起了肯定疯了

[ 本帖最后由 anlinew 于 2010-6-12 16:39 编辑 ]

使用道具 举报

回复
论坛徽章:
11
生肖徽章2007版:兔
日期:2009-11-22 14:30:45鲜花蛋
日期:2013-01-27 21:01:57茶鸡蛋
日期:2012-04-05 13:26:452012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04迷宫蛋
日期:2011-10-24 02:01:552011新春纪念徽章
日期:2011-02-18 11:42:48ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512010年世界杯参赛球队:朝鲜
日期:2010-06-30 13:46:012010新春纪念徽章
日期:2010-03-01 11:19:07
12#
发表于 2010-6-12 15:47 | 只看该作者
sp_showplan '13'
dbcc sqltext(13) 都是针对一个会话的。

没看到第二个执行计划,如何比较??

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
13#
 楼主| 发表于 2010-6-12 16:05 | 只看该作者
原帖由 andkylee 于 2010-6-12 15:47 发表
sp_showplan '13'
dbcc sqltext(13) 都是针对一个会话的。

没看到第二个执行计划,如何比较??


看4楼

使用道具 举报

回复
论坛徽章:
9
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:19:10ITPUB9周年纪念徽章
日期:2010-10-08 09:31:22ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:152013年新春福章
日期:2013-02-25 14:51:24
14#
发表于 2010-6-12 17:04 | 只看该作者
能否给出全部的执行计划,
猜想应该是改用parameter markers
之后数据库无法知道本地谓词(b.a2='111')的selectivity
因此选用了merge join。

使用道具 举报

回复
论坛徽章:
11
生肖徽章2007版:兔
日期:2009-11-22 14:30:45鲜花蛋
日期:2013-01-27 21:01:57茶鸡蛋
日期:2012-04-05 13:26:452012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04迷宫蛋
日期:2011-10-24 02:01:552011新春纪念徽章
日期:2011-02-18 11:42:48ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512010年世界杯参赛球队:朝鲜
日期:2010-06-30 13:46:012010新春纪念徽章
日期:2010-03-01 11:19:07
15#
发表于 2010-6-12 18:06 | 只看该作者
原帖由 anlinew 于 2010-6-12 16:05 发表


看4楼




绑定变量的想法是好的。
ase在15.x引入了语句缓存的新特性,比较类似绑定变量了


不知道你的版本是?
感觉在12.5.x平台上用绑定变量只能使得程序写起来简单, 不一定使得走最优的查询计划吧?

使用道具 举报

回复
论坛徽章:
114
授权会员
日期:2005-10-30 17:05:332013年新春福章
日期:2013-02-25 14:51:24奔驰
日期:2013-08-01 21:18:36宝马
日期:2013-12-04 21:52:282014年新春福章
日期: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
16#
发表于 2010-6-13 12:57 | 只看该作者
sybase 也有类似oracle table 统计信息的,不知收集和更新过吗?

使用道具 举报

回复
论坛徽章:
1
2010新春纪念徽章
日期:2010-03-01 11:06:19
17#
发表于 2010-6-13 16:19 | 只看该作者
太乱了,眼晕,能不能分别整理一下打个包,相应的SQL对应相应的执行计划。

楼上的有位同学,我明白语义左右连接和执行计划中的join的意思和区别,我不是很关心语义的写法,事实上我没怎么用过左右连接,也搞不太懂,我关心的是执行计划里面的join方式以及效率。

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
18#
 楼主| 发表于 2010-6-17 13:16 | 只看该作者
原帖由 5个周 于 2010-6-13 16:19 发表
太乱了,眼晕,能不能分别整理一下打个包,相应的SQL对应相应的执行计划。

楼上的有位同学,我明白语义左右连接和执行计划中的join的意思和区别,我不是很关心语义的写法,事实上我没怎么用过左右连接,也搞不太懂,我关心的是执行计划里面的join方式以及效率。

4楼里两个sql对应两种执行计划,很清楚啊

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
19#
 楼主| 发表于 2010-6-17 15:58 | 只看该作者
另外对于inner join 还是left join 显然是会影响执行计划里的JOIN Operator的

真实left join的情况下,右边的表是不会作为驱动表的,这就是为什么绑定变量的执行计划里 bd_psnbasdoc作为了驱动表只能全表扫描的原因

只是这里的left join 与inner join 实际上是等价的,所以我们可以看到没使用绑定变量时,left join 被转换为了inner join ,否则这里是不可能使用NESTED LOOP JOIN 的

我的问题是:为什么绑定变量了SYBASE就不能做这个转换了,哪里出了问题呢?

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
20#
 楼主| 发表于 2010-6-17 16:01 | 只看该作者
原帖由 花好月不圆 于 2010-6-13 12:57 发表
sybase 也有类似oracle table 统计信息的,不知收集和更新过吗?

做过更新

不用绑定变量或者绑定变量但用inner join 替换left join 均没问题

使用道具 举报

回复

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

本版积分规则 发表回复

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