进销存库存结构设计,视图性能

zhuxianguo 2012-11-22 11:55:11
好久没在csdn上发帖子了,公司运营一个网上订货的系统,最开始的时候是是有一个库存表,每次业务更新库存,这样的好处是查询实时库存速度很快,但是到盘点的时候总有误差,特别是业务修改涉及到的操作更多,后来改成只保留盘点期初值,然后通过一个业务视图把和库存想关的业务汇总起来,通过盘点期初数和业务视图来进行计算,这样的好处是库存准确,有业务修改,库存也会自动更正过来,因为库存是实时计算出来的,但是这样性能比较差,数据量稍微一大就查询很慢,用的sql2008,大概也就100万数据量,后来分析发现是因为视图不能利用基表的索引造成性能低下,想请教一下有没合理的折中方案。
...全文
273 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
發糞塗牆 2012-11-22
  • 打赏
  • 举报
回复
可以考虑通过存储过程控制参数的输入,从而个性化地返回数据。我不认为视图的性能很好,除非使用索引视图。但是索引视图同样有诸多限制
开启时代 2012-11-22
  • 打赏
  • 举报
回复
前两天配的话 没有出库前都是占货 ,修改这个量是可以的。 但这些占货会始终在库存计算里统计的。 实际发生以出库为准,这个没有冲突啊
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
引用 15 楼 lixzhong 的回复:
修改前两天数据??晕 已经发生的数据还可以直接改单据?
比如发货的时候发现前两天配的货中有残品,你说允许不允许修改单据,难道要放一张红单子在客户的货里面?
开启时代 2012-11-22
  • 打赏
  • 举报
回复
修改前两天数据??晕 已经发生的数据还可以直接改单据?
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
引用 5 楼 lixzhong 的回复:
第一种方法本身 就挺好的 ,误差是进销存系统难以避免的。抽盘或全盘时 校正就可以了。 如果实在不爽,就改成每天晚上跑出一个库存表,然后用业务发生做个视图 这样视图数据量比较小 。 基表里 日期做聚合索引 速度杠杠的。。。
这个方法也不是不可行,只是如果要修改前两天的数据这个方法就有问题了,可以把这个时间推到一周,这样一周前的业务就不再允许修改
开启时代 2012-11-22
  • 打赏
  • 举报
回复
引用 8 楼 zhuxianguo 的回复:
公司的业务表有:盘点表,入库表,出货表,零售表,退货表,仓库表, 视图:和库存所有相关的业务都关联到这个表了,就是一个所有产品的业务日志视图,另外,每一笔业务都涉及到两方,一个增加库存方,一个是减少库存方,这样的话如果在基本业务表一条记录在视图里面就变成了两条记录,业务表如果有100万数据,视图中就有200w 其中仓库表只是记录从何时开始计算,也就是盘点时间 这样的……
库存都是从原始社会开始算,速度上去才怪。昨日结存表+今日发生视图 速度。。。
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
如果公司盘点及时也问题不大,因为库存计算是从盘点时间点以后的业务进行计算的,可以把以前的数据转移到历史数据表,只读就可以了,但是公司最近有的库好几个月没进行盘点,造成有几个月的业务数据没有转移
开启时代 2012-11-22
  • 打赏
  • 举报
回复
引用 10 楼 zhuxianguo 的回复:
实际现在我还有一个思路就是建一个和视图一样的实体表,然后同步,不过这样也有个问题,公司网上是实时订购,如果库存更新不及时会出现订购到库存不足的产品
没有可操作性
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
实际现在我还有一个思路就是建一个和视图一样的实体表,然后同步,不过这样也有个问题,公司网上是实时订购,如果库存更新不及时会出现订购到库存不足的产品
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
/*盘点*/ SELECT '盘点+' affirm_type, order_date affirm_date, order_id, sell_id_fk, pro_no_fk, pro_num_fk, storage_finance num FROM inventory_m m, inventory_s s WHERE order_id = order_id_fk AND states_id_fk = '3' UNION ALL /*调出*/ SELECT '调库-', head_date, order_id, from_id_fk, pro_no_fk, pro_num_fk, (- 1) * num FROM storage_m m, storage_s s WHERE order_id = order_id_fk AND states_id_fk = '21' UNION ALL /*调入*/ SELECT '调库+', head_date, order_id, to_id_fk, pro_no_fk, pro_num_fk, num FROM storage_m m, storage_s s WHERE order_id = order_id_fk AND states_id_fk = '21' UNION ALL /*订单-*/ SELECT '订单-', fill_date, order_id, fill_id_fk, pro_no_fk, pro_num_fk, (- 1) * fill_num FROM order_m m, order_s s WHERE order_id = order_id_fk AND states_id_fk = '31' UNION ALL /*订单+*/ SELECT '订单+', fill_date, order_id, sell_id_fk, pro_no_fk, pro_num_fk, fill_num FROM order_m m, order_s s WHERE order_id = order_id_fk AND states_id_fk = '31' UNION ALL /*退货-*/ SELECT '退货-', fill_date, order_id, sell_id_fk, pro_no_fk, pro_num_fk, (- 1) * s.fill_num FROM return_m m, return_s s WHERE order_id = order_id_fk AND states_id_fk = '31' UNION ALL /*退货+*/ SELECT '退货+', fill_date, order_id, fill_id_fk, pro_no_fk, pro_num_fk, s.fill_num FROM return_m m, return_s s WHERE order_id = order_id_fk AND states_id_fk = '31' UNION ALL /*销售-*/ SELECT '销售-', order_date, order_id, sell_id_fk, pro_no_fk, pro_num_fk, (- 1) * num FROM sell_order_m m, sell_order_s s WHERE order_id = order_id_fk UNION ALL /*冻结-*/ SELECT '冻结-', sell_date, order_id, fill_id_fk, pro_no_fk, pro_num_fk, sell_num * (- 1) FROM order_m m, order_s s WHERE order_id = order_id_fk AND states_id_fk IN ('0', '11', '21') UNION ALL /*虚拟+*/ SELECT '虚拟+', getdate(), '-', sell_id_fk, pro_no_fk, pro_num_fk, num FROM stock_ex
zhuxianguo 2012-11-22
  • 打赏
  • 举报
回复
公司的业务表有:盘点表,入库表,出货表,零售表,退货表,仓库表, 视图:和库存所有相关的业务都关联到这个表了,就是一个所有产品的业务日志视图,另外,每一笔业务都涉及到两方,一个增加库存方,一个是减少库存方,这样的话如果在基本业务表一条记录在视图里面就变成了两条记录,业务表如果有100万数据,视图中就有200w 其中仓库表只是记录从何时开始计算,也就是盘点时间 这样的好处是程序和业务处理都很简单,因为不用担心业务结存,所有的库存都是动态计算出来的,数据量小的时候还没觉得缺点,现在所有和库存视图关联的查询都很慢,那个视图数据量太大了,而且视图不能很好的利用索引
dd_2012 2012-11-22
  • 打赏
  • 举报
回复
不要使用视图,单据表中对货品建立索引,然后改为使用存储过程,还可把结果集放到临时表
zhujinqiang 2012-11-22
  • 打赏
  • 举报
回复
2楼和4楼说得很对。 误差来源于没有采用事务处理。遇到订单修改、撤销的时候,关联的数据没有一起回退。
开启时代 2012-11-22
  • 打赏
  • 举报
回复
第一种方法本身 就挺好的 ,误差是进销存系统难以避免的。抽盘或全盘时 校正就可以了。 如果实在不爽,就改成每天晚上跑出一个库存表,然后用业务发生做个视图 这样视图数据量比较小 。 基表里 日期做聚合索引 速度杠杠的。。。
Mr_Nice 2012-11-22
  • 打赏
  • 举报
回复
引用 楼主 zhuxianguo 的回复:
好久没在csdn上发帖子了,公司运营一个网上订货的系统,最开始的时候是是有一个库存表,每次业务更新库存,这样的好处是查询实时库存速度很快,但是到盘点的时候总有误差,特别是业务修改涉及到的操作更多,后来改成只保留盘点期初值,然后通过一个业务视图把和库存想关的业务汇总起来,通过盘点期初数和业务视图来进行计算,这样的好处是库存准确,有业务修改,库存也会自动更正过来,因为库存是实……
第一种方法,如果运用好事务处理的话,应该可以避免。(推荐) 第二种方法,业务增加的话,汇总数据将会大大增加,DB会压力变大。
  • 打赏
  • 举报
回复
视图的性能真的不敢恭维 可不可以用临时表代替之?
专注or全面 2012-11-22
  • 打赏
  • 举报
回复
有误差是因为你该开事务处理的地方没有开事务处理 视图慢你可以定时跑一个job啥的,提前把数据生成好放到一个表中

34,575

社区成员

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

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