首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

sql 关于多表关联 优化有关问题

2013-03-27 
sql关于多表关联 优化问题最近 有20w 的数据执行查询,还要多表关联值(已写成试图),查询起来很慢! 求优化,

sql 关于多表关联 优化问题
最近 有20w 的数据执行查询,还要多表关联值(已写成试图),查询起来很慢! 
求优化,求解释,求解决办法!


[解决办法]
弄成视图本来就不会有什么效率提升。贴执行计划吧
[解决办法]
看了一下你的执行计划,问题有几个:
1、[ICCL_OA_20100519].[dbo].[F_Company_EU_Contact].Company_ID 这个,用了排序,估计你的聚集索引不在这个列上或者没有按照Company_ID升序来建聚集索引,这一步是开销最大的。把聚集索引建在这列或者包含这列,并按这列升序排序,可以减少这部分的开销,你这一步对33万数据排序,开销会非常大。
2、你的执行计划每部分的开销都不大,都是1~5%,但是从里面看出你的代码筛选能力非常差,看图:
sql  关于多表关联 优化有关问题
这里那么多步之后,数据量越来越大,临时结果整整4000M,也就是你带着4G的数据进行运算,之间每一步都是scan,最后返回的结果整整7999M大小,接近8G啊!你确定真的需要26万行的结果?
3、核心问题出在:F_Company_EU_Info和F_Company_EU_Contact这两个表,不能很好地筛选掉没用的数据,主要是没有where条件,所以随着这两个表的增大,你的查询会越来越慢。
4、尝试把这部分改写一下,试下使用UNION ALL或者用case when来代替多次left join

F_Company_EU_Contact a
                            LEFT JOIN ( SELECT  PP_VALUE ,
                                                PP_NAME
                                        FROM    SYSTEM_PARAMETERS
                                        WHERE   PP_TABLE = 'F_Company_EU_Contact'
                                                AND PP_FIELD = 'Status'
                                      ) b ON a.Status = b.PP_VALUE
                            LEFT JOIN ( SELECT  PP_VALUE ,
                                                PP_NAME
                                        FROM    SYSTEM_PARAMETERS


                                        WHERE   PP_TABLE = 'F_Company_EU_Contact'
                                                AND PP_FIELD = 'IS_MAINCONTACT'
                                      ) c ON a.IS_MAINCONTACT = c.PP_VALUE
                            LEFT JOIN ( SELECT  PP_VALUE ,
                                                PP_NAME
                                        FROM    SYSTEM_PARAMETERS
                                        WHERE   PP_TABLE = 'F_Company_EU_Contact'
                                                AND PP_FIELD = 'Job_Role'
                                      ) d ON a.Job_Role = d.PP_VALUE


5、还有一个核心的性能问题——视图,执行计划大量并行度运算,这个本来没多大问题,但是使用视图的话,要在执行视图的时候才编译各个表,然后生成执行计划,编译并生成执行计划是非常耗时耗资源的操作,如果没必要,就别用视图了,直接操作实体表快的多,也可以换成存储过程,这个是预编译的,能提高速度。
6、考虑一下是否有需要返回那么多列

上面的东西你改一下看看有没有效果。没有实际环境很难帮你调
[解决办法]
lz的query主要的连接是
select *
from F_Company_EU_Info a left join F_Temp_Project h
on a.TP_ID=h.TP_ID left join Sys_Mapping c 
on a.Partner_Name=c.Mapping_ID left join vw_MapToArea e 
on a.Area_ID=e.Area_ID left join F_Company_EU_Contact b
on a.Company_ID=b.Company_ID


所以先看下这段连接的执行计划是否合理,索引是否合理。

其次被多次引用的User_Info如果user_id在该表中是唯一的话可以通过自查询的方式直接在select列中写。
同样SYSTEM_PARAMETERS表中如果PP_VALUE( PP_NAME) ,PP_FIELD,PP_TABLE这三列是唯一值话也可以通过子查询的方式写在select列中。
如下。
isnull(e.Status,'<空>') as Status,


这句改成

isnull((select PP_VALUE from SYSTEM_PARAMETERS where PP_TABLE='F_Company_EU_Contact' and PP_FIELD='Status' and b.PP_VALUE=F_Company_EU_Contact.Status)'<空>') as Status,

热点排行