准备工作
1. 按照需求划分RaidGroup和LUN
2. 在存储管理界面中将新划分的LUN分配给相应服务器
3.在服务器上建新的LUN联机并格式化
4.给每个LUN分配卷名
将LUN添加进集群
1. 打开故障转移群集管理器,选择存储,点击添加磁盘,将查找到的磁盘选中,然后确定。
2. 将磁盘分配给实例(此步骤建议先将服务脱机)。
服务和应用程序,选中一个SQL Server服务,在操作栏中点击添加存储。
3. 选择想分配给这个实例的磁盘,确认
4. 修改依赖关系
选择一个SQL Server服务,在其它资源中双击SQL Server服务,出现属性窗口,选择依赖关系--插入
5. 切换及做一些必要的验证
今天在工作中统计一个数据,最开始比较顺利的执行完了sql,但后来用户稍稍调整了需求,本来我以为增加一个查询条件就可以搞定的事情,结果执行了二十多分钟才出结果。后来我查看了下执行计划,发现前后两个sql的执行计划有变化。
这两个SQL分别为:
SELECT T.YEARID, SUM(T.EXPORTSUM) FROM STDW.F_CUSTOM_EXPORTDETAIL T, (SELECT A.ZONE, A.ZONE_NAME FROM STDW.D_CUSTOM_PROVINCE_ZONE A, STDW.D_CUSTOM_BRANCH_PROVINCE B WHERE A.PROVINCE_NO = B.PROVICEID AND B.CORPID = 4400) T2 WHERE T.CITYNO = T2.ZONE AND (T.CUSTOMCODE8 LIKE '03061%' OR T.CUSTOMCODE8 LIKE '03%' OR (T.CUSTOMCODE8 LIKE '16%' AND T.CUSTOMCODE8 NOT LIKE '1601%' AND T.CUSTOMCODE8 NOT LIKE '1602%')) AND T.YEARID BETWEEN 2010 AND 2012 GROUP BY T.YEARID
SELECT T.YEARID, SUM(T.EXPORTSUM) FROM STDW.F_CUSTOM_EXPORTDETAIL T, (SELECT A.ZONE, A.ZONE_NAME FROM STDW.D_CUSTOM_PROVINCE_ZONE A, STDW.D_CUSTOM_BRANCH_PROVINCE B WHERE A.PROVINCE_NO = B.PROVICEID AND B.CORPID = 4400 AND B.PROVICEID = 44) T2 WHERE T.CITYNO = T2.ZONE AND (T.CUSTOMCODE8 LIKE '03061%' OR T.CUSTOMCODE8 LIKE '03%' OR (T.CUSTOMCODE8 LIKE '16%' AND T.CUSTOMCODE8 NOT LIKE '1601%' AND T.CUSTOMCODE8 NOT LIKE '1602%')) AND T.YEARID BETWEEN 2010 AND 2012 GROUP BY T.YEARID
第一个SQL的执行计划为:
第二个SQL执行计划为:
这里需要说明一下背景,表F_CUSTOM_EXPORTDETAIL是一个按年进行分区的表,每个分区下都是千万级别以上的数据量,差不多都是三、四千万的数据量。对于表D_CUSTOM_BRANCH_PROVINCE,CORPID字段为4400的数据有两条,PROVICEID字段为44的数据只有一条。
在第一次只限制CORPID=4400时,SQL执行时间差不多2分钟(毕竟表F_CUSTOM_EXPORTDETAIL较大),看执行计划还比较合理。但在第二次再增加限制条件"B.PROVICEID = 44"后,SQL执行时间明显变长,差不多要20多分钟。通过分析这两个SQL的执行计划,发现第二条SQL的执行计划有变化:表的连接方式变成了NESTED LOOPS。如果表数据量大的时候,这种方式是比较耗时的。
之前遇到的情况是相同的SQL,相隔一段时间后执行计划发生了变化,原因在于统计信息没有及时收集,解决方案是利用了oralce的hint。但这次和之前的情况不太一样,毕竟SQL不太一样,且这两条SQL的执行计划都是固定的。为了摸清根源,这次没有利用hint,而是去分析了第二条SQL。
前面也提到,增加了条件"B.PROVICEID = 44"后,D_CUSTOM_BRANCH_PROVINCE只有一条记录,这是ORACLE会自作聪明的进行使用NESTED LOOPS表连接方式,实际上也是有道理的,但是因为最后关联的表F_CUSTOM_EXPORTDETAIL数据量过大,才导致执行效率低下。在这种情况下比较好的办法是使用HASH JOIN表连接方式,怎么样才能做到呢?根据前面的分析,我们应该首先考虑到破除只有一条记录这种可能。分析第二条SQL里面的子查询:
SELECT A.ZONE, A.ZONE_NAME FROM STDW.D_CUSTOM_PROVINCE_ZONE A, STDW.D_CUSTOM_BRANCH_PROVINCE B WHERE A.PROVINCE_NO = B.PROVICEID AND B.CORPID = 4400 AND B.PROVICEID = 44
由于D_CUSTOM_BRANCH_PROVINCE限制条件后只有一条记录,且D_CUSTOM_PROVINCE_ZONE和该表进行关联时用到了PROVICEID,那我们可以不用D_CUSTOM_BRANCH_PROVINCE,直接限制表D_CUSTOM_PROVINCE_ZONE的条件,如下:
SELECT A.ZONE, A.ZONE_NAME FROM STDW.D_CUSTOM_PROVINCE_ZONE A WHERE A.PROVINCE_NO = 44
这下就完全和表D_CUSTOM_BRANCH_PROVINCE脱离了干系,但实际效果是一样的。
最后SQL修改为:
SELECT T.YEARID 年份, SUM(T.EXPORTSUM) 出口金额 FROM STDW.F_CUSTOM_EXPORTDETAIL T, (SELECT A.ZONE, A.ZONE_NAME FROM STDW.D_CUSTOM_PROVINCE_ZONE A WHERE A.PROVINCE_NO = 44) T2 WHERE T.CITYNO = T2.ZONE AND (T.CUSTOMCODE8 LIKE '03061%' OR T.CUSTOMCODE8 LIKE '03%' OR (T.CUSTOMCODE8 LIKE '16%' AND T.CUSTOMCODE8 NOT LIKE '1601%' AND T.CUSTOMCODE8 NOT LIKE '1602%')) AND T.YEARID BETWEEN 2010 AND 2012 GROUP BY T.YEARID
执行计划为:
这下执行SQL又只要2分钟左右了。
总结:
1、理论上来说可选择性越高,SQL执行效率越高,但也要分情况:如果查询的结果只有一条了,可能会影响到表之间的关联方式,导致执行效率低下。
2、查看执行计划时要多注意表之间的连接方式,而且要多想想ORACLE为什么要采用此方式,这样有助于解决问题。