【大家帮帮忙,大数据量的处理方法】

viva369 2008-04-05 11:17:38
先说明一下我的环境
有1个客户表大约我100多万的数据,1个是客户就读的中心表1000条左右,一个是客户访问记录的表80万左右。。
首先查询条件很多,比如说有手机号,姓名等等,但有个相同的条件就是数据权限,也就是登陆用户管理哪个中心就出现哪个中心的数据

比如说登陆用户管理杭州的某中心,那么客户表里就读中心字段IN(管理中心的ID),或者是学员曾经访问过他管理的中心,

最后出来的条件就是== 客户表.就读中心字段IN(管理中心的ID) or 客户表.ID IN (访问记录表.客户表.ID),这样速度就很慢很慢了,

希望听听大家有什么好的优化建议,不慎感激!!
...全文
192 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
yimeng123 2008-04-07
  • 打赏
  • 举报
回复
重薪诚聘C++
http://topic.csdn.net/u/20080227/14/8bce0844-bd15-42f0-9cda-a343d5d6601b.html
viva369 2008-04-07
  • 打赏
  • 举报
回复
大家请看我的新帖

http://topic.csdn.net/u/20080407/09/d81f91ef-a5b4-4891-9e66-2a54dc2edfc7.html

这贴我结了,谢谢大家的帮忙!
wlinglong 2008-04-07
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 viva369 的回复:]
引用 26 楼 wlinglong 的回复:
用存储过程配合临时表 将条件分解, 就是把你的OR 语句分解成2个 单独的查询 然后再进行组合 这样我想应该能提高点速度


2个查询放到临时表,每个查询都有100万记录,插入临时表的时间开销太大了!
[/Quote]
确实, 直接吃内存

我的想法就是把你的OR语句分开, 你没有必要用oR 太影响速度, 你可不可以 用UNION连接一下结果 这个速度方面我还真不太了解 但是我想应该比OR会快 你试试吧

小小菜鸟 发表一下议论 ^_^
ojuju10 2008-04-07
  • 打赏
  • 举报
回复



优化你的表,将你所需要的数据都放在一个临时表里面,经常维护和同步这个临时表里面的数据,

最好不会进行连接查询
viva369 2008-04-07
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 wlinglong 的回复:]
用存储过程配合临时表 将条件分解, 就是把你的OR 语句分解成2个 单独的查询 然后再进行组合 这样我想应该能提高点速度
[/Quote]

2个查询放到临时表,每个查询都有100万记录,插入临时表的时间开销太大了!
ojuju10 2008-04-07
  • 打赏
  • 举报
回复

优化你的表,最后不会进行连接查询
wlinglong 2008-04-07
  • 打赏
  • 举报
回复
用存储过程配合临时表 将条件分解, 就是把你的OR 语句分解成2个 单独的查询 然后再进行组合 这样我想应该能提高点速度
flairsky 2008-04-07
  • 打赏
  • 举报
回复
改用动态sql

具体的就是把in改了
viva369 2008-04-07
  • 打赏
  • 举报
回复
再顶一个~
viva369 2008-04-06
  • 打赏
  • 举报
回复
继续顶~
-狙击手- 2008-04-06
  • 打赏
  • 举报
回复
(管理者负责的中心) OR 字典表.PKID IN (管理者负责的中心)



管理者负责的中心 是不定的吧? 上例61 仅是一个特例?
viva369 2008-04-06
  • 打赏
  • 举报
回复
可以简化成下面的代码,

select top 15 *
from Client --客户表
LEFT JOIN InfoSourceCategory ON InfoSourceCategory.PKID = Client.FK_InfoSourceCategory AND InfoSourceCategory.IsValid = 1
LEFT JOIN CallHistory ON CallHistory.PKID = Client.FK_CallHistory AND CallHistory.IsValid = 1 --访问记录表
LEFT JOIN Dictionary A ON A.PKID = CallHistory.FK_Center AND A.IsValid = 1
LEFT JOIN Dictionary B ON B.PKID = Client.FK_ExtendCenter AND B.IsValid = 1
where 1=1 AND ((Client.FK_Center IN(61) OR A.PKID IN (61)) AND Client.IsValid = 1 ) --***影响性能的地方
order by Client.PKID desc


Client--998121
CallHistory --856729
Dictionary --112
dawugui 2008-04-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 viva369 的回复:]
引用 8 楼 dawugui 的回复:
引用 4 楼 viva369 的回复:
exists 改过了,索引该+的都加的,但在服务器上执行一个分页往往还是要7-8秒左右

嗨,其实数据量并不是很大,上亿的数据也就认栽了,但区区100多万有点不甘心!!!

去掉or旁边任何一个速度则在1-2秒,怎么办啊~~~


改or 为 union all试试.

select * from .... where 客户表.就读中心字段IN(管理中心的ID)
union all
select * from ...…
[/Quote]
那就用union

改or 为 union试试.

select * from .... where 客户表.就读中心字段IN(管理中心的ID)
union
select * from .... where 客户表.ID IN (访问记录表.客户表.ID)
pt1314917 2008-04-06
  • 打赏
  • 举报
回复
很好很强大。
viva369 2008-04-06
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 happyflystone 的回复:]
(管理者负责的中心) OR 字典表.PKID IN (管理者负责的中心)


管理者负责的中心 是不定的吧? 上例61 仅是一个特例?
[/Quote]

是的,也可能有多家中心,比如说系统管理员那就是所有的权限~
viva369 2008-04-05
  • 打赏
  • 举报
回复
Client.FK_Center IN(61) OR A.PKID IN (61))
客户表.中心 IN(管理者负责的中心) OR 字典表.PKID IN (管理者负责的中心)

中心在字典表里维护~

问题就出在这里,有什么办法优化~
-狙击手- 2008-04-05
  • 打赏
  • 举报
回复
Client.FK_Center IN(61) OR A.PKID IN (61))


?????????
viva369 2008-04-05
  • 打赏
  • 举报
回复

select top 15 *
from Client --客户表
LEFT JOIN InfoSourceCategory ON InfoSourceCategory.PKID = Client.FK_InfoSourceCategory AND InfoSourceCategory.IsValid = 1
LEFT JOIN InfoSourceDetail ON InfoSourceDetail.PKID = Client.FK_InfoSourceDetail AND InfoSourceDetail.IsValid = 1
LEFT JOIN DataImportType ON DataImportType.PKID = Client.FK_DataImportType
LEFT JOIN VisitType ON VisitType.PKID = Client.FK_VisitType
LEFT JOIN CallHistory ON CallHistory.PKID = Client.FK_CallHistory AND CallHistory.IsValid = 1 --访问记录表
LEFT JOIN Dictionary A ON A.PKID = CallHistory.FK_Center AND A.IsValid = 1
LEFT JOIN Dictionary B ON B.PKID = Client.FK_ExtendCenter AND B.IsValid = 1
LEFT JOIN InboundResult ON InboundResult.PKID = CallHistory.FK_InboundResult AND InboundResult.IsValid = 1
LEFT JOIN OutboundResultType ON OutboundResultType.PKID = CallHistory.FK_OutboundResultType AND OutboundResultType.IsValid = 1
LEFT JOIN OutboundResultDetail ON OutboundResultDetail.PKID = CallHistory.FK_OutboundResultDetail AND OutboundResultDetail.IsValid = 1
LEFT JOIN VisitHistory ON VisitHistory.PKID = Client.FK_VisitHistory AND VisitHistory.IsValid = 1
LEFT JOIN Dictionary C ON C.PKID = VisitHistory.FK_Center AND C.IsValid = 1
LEFT JOIN [User] CC ON CC.PKID = Client.FK_CC AND CC.IsValid = 1
LEFT JOIN [User] Tutor ON Tutor.PKID = Client.FK_Tutor AND Tutor.IsValid = 1
INNER JOIN Contract ON Contract.FK_Client = Client.PKID AND Contract.IsValid = 1
INNER JOIN ContractStatusType ON ContractStatusType.PKID = Contract.FK_ContractStatusType AND ContractStatusType.IsValid = 1 -- and ContractStatusType.pkid = 2
LEFT JOIN CourseLevel BeginLevel ON BeginLevel.PKID = Contract.FK_BeginLevel AND BeginLevel.IsValid = 1
LEFT JOIN CourseLevel CurrentLevel ON CurrentLevel.PKID = Contract.FK_CurrentLevel AND CurrentLevel.IsValid = 1
LEFT JOIN CourseLevel EndLevel ON EndLevel.PKID = Contract.FK_EndLevel AND EndLevel.IsValid = 1
LEFT JOIN ContractType ON ContractType.PKID = Contract.FK_ContractType AND ContractType.IsValid = 1
where 1=1 AND ((Client.FK_Center IN(61) OR A.PKID IN (61)) AND Client.IsValid = 1 )
and (1=1 AND (Client.PKID IN (SELECT FK_Client FROM Contract WHERE FK_ContractStatusType = 2 AND IsValid = 1) ))
--因为合同表中一个客户存在2个合同的情况,而且状态不一致。所以此处在=2的条件和在ContractStatusType连接时加=2的条件所产生的结果是不一样的
order by Client.PKID desc


上面是具体的SQL,帮忙分析分析,万分感激~
viva369 2008-04-05
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 happyflystone 的回复:]
直接关联访问记录表呢
[/Quote]

--客户表要连接10多个表,访问记录的表也在连接之内,最后where中写了这个条件的。
viva369 2008-04-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jinjazz 的回复:]
你这两个or的重量级明显不一样...
第一个建议改为exists或者n个or语句配合索引
第二个就要好好考虑了。

ps:10w记录,真的有必要一次查询出来么
[/Quote]

分页的时候取top 15,但是必须要符合这个条件出来的数据才是正确的。。。

是不是要采用终极的解决办法,分在不同的服务器上什么的办法了??

晕死了~~
加载更多回复(12)

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧