当前位置: 代码迷 >> Sql Server >> 非常实际的一个有关问题,想了很久了partition by该不该用
  详细解决方案

非常实际的一个有关问题,想了很久了partition by该不该用

热度:79   发布时间:2016-04-24 09:50:56.0
非常实际的一个问题,想了很久了partition by该不该用
标题可能起的不太合适,感谢大神能够进来参观案发现场!!
MSSQL Server 2008

系统功能:一个垂直行业网站,会员注册可以发布信息,数据量现在不大但是以后会逐渐增加
实现功能:根据【1】信息发布时间的日期(yyyy-MM-dd)、【2】该信息在会员发布信息中的行号(为了防止一个会员在短时间内发布大量信息占前排,这样一个会员在第一页就只有一条信息了)、【3】会员等级、【4】信息发布时间排序。
为了更好的说明这个问题,模拟一个环境

T1   userid   viplevel
     001       1
     002       2
T2   infoid   infotitle   createuser    createtime
     1        信息1       001           2014-10-20 08:30:30
     2        信息2       001           2014-10-20 10:30:30
     3        信息3       002           2014-10-20 06:30:30
     4        信息4       002           2014-10-21 08:30:30
     5        信息5       002           2014-10-21 09:30:30
     6        信息6       001           2014-10-21 11:30:30

希望排列序号为:5,6,4,3,2,1
------------------------------------
现在只做了首页列表,首页现在测试没问题(现在数据量不大)

这个是首页的列表只取前20条
select top 20 t.*,viplevel = (case when t2.vipendtime<GETDATE() then '0' else t2.viplevel end) from
(select ROW_NUMBER() over(partition by t1.createuser order by t1.ordertime desc) rownum,t1.id,t1.title,t1.ordertime,t1.createuser from MM_purchase t1 where t1.lock =1) t
left join MM_user t2 on t.createuser = t2.username
where t.rownum = 1 and t2.lock =1
order by CONVERT(VARCHAR(10),t.ordertime,112) desc,viplevel desc,t.ordertime desc
现在解释下:其中viplevel = (case when t2.vipendtime<GETDATE() then '0' else t2.viplevel end)是计算会员等级的数据库中是使用viplevel 和vipendtime来判断会员到期后按等级0计算
MM_purchase ==>t2 MM_user ==>t1 ordertime==>createtime
------------------------------------
现在问题来了:
1.如果内页(列表页)也使用这种方式数据量大时效率会怎么样?首页可以做缓存列表页可不能,如果不行放弃条件【2】后行不行?有没有好的方法或者逻辑?
2.会员等级的这种设计方式是不是效率有很大影响,对于这种情况一般是怎么样处理的(人工改不现实,条件有限(使用的万网云空间),无法单独写循环处理软件)?
3.在首页的那整条语句中viplevel = (case when t2.vipendtime<GETDATE() then '0' else t2.viplevel end) 对后面的viplevel(order by CONVERT(VARCHAR(10),t.ordertime,112) desc,viplevel desc)产生了影响,但是在例如row_number() over(order by t1.ordertime desc) rownum 分页排序中后面条件(where)就无法直接使用rownum这个字段,这两种情况的执行顺序是怎么样的?为什么会不同?  
表达可能不大好,见谅,受累了.
------解决思路----------------------
没有看懂你的列子的排序规律在哪里?
还有你只是根据
【1】信息发布时间的日期(yyyy-MM-dd)、【2】该信息在会员发布信息中的行号(为了防止一个会员在短时间内发布大量信息占前排,这样一个会员在第一页就只有一条信息了)、【3】会员等级、【4】信息发布时间排序。
具体怎么根据这些条件进行综合考虑 你也没说。
我觉得可以设置一个权重。比如说。
信息发布时间如果都是今天 那么都是10,昨天是5 在一起就是0,
根据这个记录在发布人里面的时间排序 如果是第一(改发布人最后发布的信息) 那么是10,
第二就是5,然后就是0,
根据会员等级进行设置。高级会员是10,低级会员是5,如果时间都是今天。在按照时间排序。最新是10 然后9
最后进行累加。占比最大就是第一行。然后。。。
------解决思路----------------------
2)T1 添个计算列,用它排序
realVipLevel AS case when t2.vipendtime<GETDATE() then '0' else t2.viplevel end
--level 不要用字符,你自己换成 int


3) row_number() 是先筛选出结果再排号的,如果能在 WHERE 条件中计算岂不结果的行号可能会不连续?
不会那样设计的。
------解决思路----------------------
引用:
Quote: 引用:

2)T1 添个计算列,用它排序
realVipLevel AS case when t2.vipendtime<GETDATE() then '0' else t2.viplevel end
--level 不要用字符,你自己换成 int


3) row_number() 是先筛选出结果再排号的,如果能在 WHERE 条件中计算岂不结果的行号可能会不连续?
不会那样设计的。


您说的计算列是在数据库中添加还是 在sql语句中?应该是语句中吧 是这样的方式吗?
realVipLevel = (case when t2.vipendtime<GETDATE() then 0 else t2.viplevel end)   用AS看不懂啊

添加在数据表结构上
ALTER TABLE MM_user  ADD realVipLevel AS case when vipendtime<GETDATE() then '0' else viplevel end
  相关解决方案