27,582
社区成员
发帖
与我相关
我的任务
分享
SELECT *
FROM mt_house_relationPer_tbl_zq20130308
ORDER BY hou_client asc


select a.id
from mt_house_relationPer_tbl_zq20130308 a
where
exists( select id from get_Perinfo_fordept_fun('67,91',3 ) as getPer where del=1
AND hou_client= getPer.id )
order by a.id desc

select a.id
from mt_house_relationPer_tbl a
where
exists( select id from get_Perinfo_fordept_fun('67,91',3 ) as getPer where del=1
AND add_per= getPer.id )
order by a.id desc 
说吧,我查漏补缺
周六日有点事,而且刚好没网络,没回复,不过还是吓我一跳,那么多问题,我一个一个来吧,尽量尽量,为了不影响我的思路连贯性,可能不会针对你的每一个问题单独回复,希望你能看得懂。
1、我看你的表mt_per_tbl 上索引那么多,会不会存在过度使用了?
2、对于你11楼的问题,不同的列很难有可比性,因为:a、数据类型的差异,哪怕char10和char20,性能都会存在可能性的差异,当然优化器也有可能优化成没有差异。b、数据分布,这个才容易造成性能差异。如果某个列存在大量相同的值,或者空值,那么它的“选择性”就相对较低,索引也相对低效。还要视乎你的统计信息是否及时。统计信息和索引的列、索引的碎片等等都会对优化器选择造成决定性的影响。这里有个建议:把你的两个查询都分别这样做:分别对同一个查询点预估执行计划和实际执行计划,看看这两者是否在某些部分有明显差异,如果有,很有可能意味着你统计信息或者碎片影响了,如果没有,再考虑其他。
3、还是11楼的问题,select * into 只是把数据和结构导过去,但是不会把索引、约束这些导过去,如果你没有手工创建,你知道后果的。
4、索引的高明之处就在于避免每次查询都要读每一行,合理的索引可以把数据或者数据的标识符存放到索引页,由于索引页由B-TREE组成,所以即使大量数据,索引的深度都不会非常变态,深度决定索引的查找速度。这个暂时不深入说,几十万字恐怕也说不清楚。何况我也不是理解透。简单说一下,假设你有聚集索引(也就是有了整个表的数据),那么如果你的数据分布靠前,那么分布在索引树上,就是靠左边的节点,而扫描索引是从左边开始,那么所谓先到先得,自然就快。
5、我觉得你的cte可以考虑改进一下,如考虑是否有必要改表结构、有没有必要加where条件限制返回结果集。然后把cte的筛选条件参数化,在使用函数的时候改成直接关联这个CTE的结果集或者这个结果集的临时表 。这样会有提高,特别大大数据量的时候都会有。
6、对于临时表,很少应用必须用到全局临时表,而你这个我觉得还不至于,所以用局部临时表就可以了,对于性能问题,主要就是tempdb的管理了。还有记得用完马上删除而不要在存储过程的最后才删除。
7、11楼最后一个问题:并行度,这个主要靠SQLServer控制,你很难控制的。因为系统动态根据运行时的负载来决定是否有可用的资源做并行操作,每个执行计划一个实例下最多只有两个,一个就是并行、一个就是串行。你把数据赋值过去,其实基本上不就等于同一个列嘛,那有什么好对比的。列的数据、数据类型、数据分布、索引(创建顺序、碎片程度、列的查找、扫描次数等等)都会对执行的结果有影响,这个好像说的太深了...
8、复合索引的列顺序也有影响,筛选性高的列放在前面,那么它会尽快减少需要处理的数据集,如果放在后面,那么索引筛选性能就相对低,需要面对的数据量也就大,如果数据量到达一定程度,就会使用哈希来替代嵌套循环这种情况的发生。
9、移除函数是提升性能比较有效的方法,详细可以看看我的文章:http://blog.csdn.net/dba_huangzj/article/details/7816384
10、总结性的一句,当发生不同的关联方式时,要考虑关联操作的两边结果集,有什么不同,比如使用哈希关联的两个表比使用嵌套循环的两个表是否相对来说大很多?是否那些列上没有索引或者没有排序等等因素,因为这些因素是影响关联方式的主要方式。不过要记住,没有绝对好的关联方式,也没有绝对差的关联方式,各有千秋,且视实际情况而定。
不知道有没有遗漏,有问题继续问吧。我有空会回答,但是不保证实时性,最近有新任务,忙。
夜深、睡觉了
exec test --这里有插入临时表
select * from #TMP --这样是会报错的
select a.idfrom mt_house_relationPer_tbl_zq20130308 a
inner join ( select id from get_Perinfo_fordept_fun('67,91',3 ) where del=1) b
on a.hou_client= getPer.id
order by a.id desc
有表值函数的关系, 试下这个。如果速度不行 还是建议用临时表。
--根据部门(区域)ID串,得到包括本身部门(区域)及所有子集部门(区域)下的所有人(包含离职
;with wsp as
(
select id,dept_name from agent_config.dbo.Agent_Department_Tbl where CHARINDEX(','+CAST(id AS VARCHAR(100))+',',','+@dept_id+',')>0 and isnull(del,0)=0
union all
select a.id,a.dept_name from agent_config.dbo.Agent_Department_Tbl a,wsp b where a.parent_id=b.id and isnull(a.del,0)=0
)
insert into @t
select per.id,per_name,ISNULL(per.del,1) del
from wsp a
inner join agent_config.dbo.mt_shop_tbl shop on a.id=shop.dept_id --这里把只查询未删除店的条件去掉了,因为数据查看下成交房源需要查看到所有人的,包含已删除的店
inner join agent_config.dbo.mt_per_tbl per on per.per_shop=shop.shopid
UNION
SELECT per.id,per_name,ISNULL(per.del,1) del
FROM wsp a
INNER JOIN agent_config.dbo.mt_per_tbl per on a.id=per.DEPT_IDselect id from get_Perinfo_fordept_fun('67,91',3 ) as getPer where del=1

