系统要求扫描产品的条码,保存进数据库,条码不能重复。
系统很简单,但每天的数据量非常大,基本要7万条/天,所以当数据总量达到200万的时候,系统插入记录时就会非常慢,我目前的检查重复是通过设置条码栏位为唯一索引,在程式中捕捉sql返回的错误来判断,这样比传统的用语句判断是否唯一已经快很多,但在数据量大时还是十分缓慢。数据库采用的sql2000.现在没办法只能定期转移数据,实在是非常麻烦。
请教是否有更好的方法处理,谢谢!!!

解决方案 »

  1.   

    在内存里建个hash,把条码存在这个hash里,扫描后先检查重复。
      

  2.   

    在内存里建个hash,把条码存在这个hash里,扫描后先检查重复。
    ----不但是一台电脑输入,多台电脑输入,而且还要检查与之前的条码是否重复
      

  3.   

    每日7W以上是BARCOAD吧?
    按日期建表
      

  4.   

    用if not exists(select akey from a where akey='1234')
        insert into a values(akey, b,c,d)
      

  5.   

    有助于sqlserver编程的综合应用 很值得关注
      

  6.   

    楼主,首先我想确定一下,你所说的“条码不能重复”的限制范围是什么,就像超市里刷东西,重复的只是同一张单而已,如果一样东西我买了两个,刷了两次,第一次新增,而第二次是update + 1。总不会是无任何限制的“条码不能重复”吧?假设是以天来限制重复条码,如楼上几位所说,按日期来建表是一个不错的方案。另外,如果你知道所有条码的话,不妨每天insert进所有条码,加一个字段统计扫描次数,每扫一次直接扫描次数update + 1,到时候要统计的时候where 次数>0即可,过期数据直接delete where 扫描次数=0
      

  7.   


    高性能网站建设之 MS Sql Server数据库分区 
    什么是数据库分区?
    数据库分区是一种对表的横向分割,Sql server 2005企业版和之后的Sql server版本才提供这种技术,这种对表的横向分割不同于2000中的表分割,它对访问用户是透明的,用户并不会感觉的表被横向分割了。(2000中的表横向分割是建n个表例如按时间建表每月一个表,表名不同,最后需要做一个大视图)关于具体的如何做分区,请参考数据库分区演练http://www.cnblogs.com/yukaizhao/archive/2008/05/07/sql_partition_test.html 为什么要分区?
    显而易见分区是为了提高数据库的读写性能,提高数据库的效率;分区是否总是可以提高效率?
    分区是一把双刃剑,并不总能提高效率,这和具体情况有关系。
    之所以有分区技术,分区技术用的好的话可以提高性能,是因为一方面分区把一大块数据分成了n小块,这样查询的时候很快定位到某一小块上,在小块中寻址要快很多;另一方面CPU比磁盘IO快很多倍,而硬件上又有多个磁盘,或者是RAID(廉价磁盘冗余阵列),可以让数据库驱动CPU同时去读写不同的磁盘,这样才有可能可以提高效率。
    分区在有些时候并不能提高读写效率,比如说我们经常看到的按照日期字段去分区MSDN例子,这个实例中是按照记录的生成时间来分区的,把一年的数据分割成12个分区,每月一个。这样的分区导致分区并不能实现CPU同步写并提高写入性能,因为在同一个时段CPU总是要写入到最新的那一个分区对应的磁盘中。另一个问题是:这样分区是否可以提高读取性能呢?答案是不一定,要看根据什么字段来查询,如果是根据时间来查询,根据时间生成报表那么这种分区肯定会提高查询的效率,但是如果是按照某个客户查询客户最近1年内的账单数据,这样数据分布到不同的分区上,这样的话效率就不一定能提高了,这要看数据在同一个分区上连续分布的读性能高,还是CPU从几个磁盘上同步读取,然后在合并数据的性能更高一些,这和读取数据的记录数也有关系。如何分区?用什么字段做分区依据?
    具体如何分区和涉及的业务有关系,要看业务上最经常的写入和读取操作是什么,然后再考虑分区的策略。既然与具体业务相关,我们就假定一个业务环境,假如我们要做一个论坛,对论坛的帖子和回复表进行分区。
    论坛中最常见的写操作是1)发帖 2)回复帖子,
    最常见的读操作是
    1) 根据帖子id显示帖子详情和分页的帖子回复 
    2) 根据帖子版面帖子列表页根据版面id分页读取帖子列表数据
    怎么分区更合适呢?现在还没有准确答案,我有两种可能的方案,写下来,大家讨论看看。
    方案1. 根据帖子ID区域段分区(1-300w一个分区、300w-600w一个分区…),这样理论上可以提高帖子详细页的读取速度,而对于写操作性能没有益处,对于根据版面id读取帖子列表页有可能有益
    方案2. 根据版面id进行分区,这样对于写性能应该有提高,不同的分区对应不同的版面,当有两个版面同时有发帖回帖操作时,有可能可以并发写。对于根据版面id获得帖子列表页数据也可以提高性能,而对于帖子详细信息页没有性能影响。多大的数据量才需要分区?
    这个问题我只能说一个内部标准,如果一张表的记录超过在超过1000w,并以每月百万的数据量增长,那就需要分区。大家有不同的看法请回复讨论关于具体的如何做分区,请参考数据库分区演练http://www.cnblogs.com/yukaizhao/archive/2008/05/07/sql_partition_test.html[code=SQL]代码加注释,希望对初学者有用。USE [master]
    GO
    if exists (select * from sys.databases where name = 'Test_1')
    drop database Test_1
    GO
    --创建新库,要演练分区所以我们会多创建两个文件组Test_A,Test_B,以便在后面的分区方案中使用。
    CREATE DATABASE [Test_1] ON  PRIMARY 
    ( NAME = N'test_1', FILENAME = N'D:\sqldata\test_1.mdf' , SIZE = 10240KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ),
     FILEGROUP [test_A] 
    ( NAME = N'Test_A', FILENAME = N'D:\sqldata\test_A.ndf' , SIZE = 1024KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ),
    FILEGROUP [test_B] 
    ( NAME = N'Test_B', FILENAME = N'D:\sqldata\test_B.ndf' , SIZE = 1024KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'Test_log', FILENAME = N'D:\sqldata\Test_log.ldf' , SIZE = 7616KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
     COLLATE Chinese_PRC_CI_AS
    GO
    USE [Test_1]
    GO
    --若分区函数存在则先drop掉
    IF  EXISTS (SELECT * FROM sys.partition_functions WHERE name = N'test_partition')
    DROP PARTITION FUNCTION [test_partition]
    GO
    /**//*创建分区函数给后面的分区方案使用,分区函数很简单就是指定一个范围确定在某个值为什么的时候放在那个分区上*/
    --新建一个简单的分区函数,该函数以1000为界分两个区
    create partition function test_partition(int)
    AS
    RANGE LEFT FOR VALUES (1000) 
    go
    /**//*看分区方案是否存在,若存在先drop掉*/
    IF  EXISTS (SELECT * FROM sys.partition_schemes WHERE name = N'test_scheme')
    DROP PARTITION SCHEME test_scheme
    GO
    --创建分区方案,分区方案需要指定一个分区函数,并指定在分区函数中分的区需要放在哪一个文件组上
    create partition scheme test_scheme 
    AS 
    PARTITION [test_partition] TO (test_A,test_B)
    GO
    --创建分区表
    if object_id('student','U') is not null
    drop table student;
    go
    create table student
    (
        id int identity(1,1) not null,
        name varchar(10) not null,
        class int not null,
        grade int
    ) on test_scheme(class) --在此处指定该表要使用的分区方案,并将指定分区依据列
    go
    --随便插入几条数据
    insert into student values ('AQU',10,100); -- 这条数据在A分区上
    insert into student values ('AQU_边界',1000,89); -- 这边数据也在A分区上是个边界,因为我们上面在函数中指定的是RANGE LEFT,所以1000在A分区上
    insert into student values ('BQU',1001,90); -- 这一条肯定是在B分区上了。go
    --最后看看结果。$partition.分区函数(分区列)可以返回某一行所在的分区序号
    select *,分区序号 = $partition.test_partition(class) from student
    GO
      

  8.   

    7W/天,200W以上就慢?
    你不会用什么感知组件,将200W条数据显示给用户看吧?你自己在200W的表,用查询分析器手工insert一条数据,它要几秒?如果它不需要时间,那说明是程序问题,程序问题,一般就是使用感知组件,或者显示大量数据,你觉得客户吃饱了撑着,会从100以上的记录去查找自己需要的数据吗?
      

  9.   

    我也觉得很大程度上是你客户端程序的问题,比如你放了个dbgrid,显示所以数据,又或者你使用了recordcount或者last等涉及到全表操作的语句,否则没有你说的那么慢。
    我们整体操作百万千万的数据,也没看怎么慢。
    另外,大数据的处理。定期维护索引是必须的,在空闲的时候(大部分是半夜),重建索引
      

  10.   

    基于你的数据量较大,每次都去查询数据总不是理想的,
    建议每天的条码都有一定的规则,如:以XXX+日期+XXX等等的格式,
    如果是这样,我们就可以这样做:
    1.先判断条码是否符合格式(客户端判断).
    2.将一天的数据存在一个中转表中,这样在一天几万条数据判断重复就显得效率快
    3.第二天将数据自动转入到正式表中(正式表如果太大,超过千万级的话才建议可以考虑分区,索引等等).
      

  11.   

    200万的数据就喊慢,99%是程序写法的问题,
    楼上有个朋友说是数据感知控件的问题,如果一次打开很多数据,那确实是这个问题,
    建议select * from tbl where 1=2 来打开数据感控件。我的数据到2000万的时候有点慢了,解决办法如下:
    1.增加一int类型的主键。
    2.撤销条码的主键。
    3.插入时不判断重复。
    4.插入后再去处理重复条码。
      

  12.   

    同意 vfork 的说法。我们估一个系统,单表存3000万数据都不觉得怎么非常慢。
      

  13.   

    你这个判断条码是否重复的过程,应该放到SQL里做校验,程序里校验肯定慢,这个放到数据库层校验,负荷和性能都优于程序判断
    一方面加唯一索引在条码字段上,一方面复杂的校验可以设置CHECK约束,支持正则表达式的。
      

  14.   

    SQL2000好像不能分区,只能分表,再加视图
      

  15.   

    1.一秒之内都应该可以接受
    2.并发输入在30台电脑左右
    3.数据库服务器的配置志强2.8双核CPU两个,内存2G
    4. 条码不能重复是指表中任意时期记录的条码都不能重复
    5. 应用系统是局域网
      

  16.   

    我提供一个思路:
      1.建立一个日期字段(精确到秒),并在此字段建立聚集索引;
      2.不要把主键建立在条码上,建立int类型的主键字段;
      3.修改条码的组合方式,加入日期组合,这样在查询重复时先分离出日期,利用聚集索引缩小搜索范围,减少查询时间;
      4.楼上有人说利用分区表的方式,但是sql2000的分区表是利用分区视图实现的,效果不理想,在7万条/天的数据量上维护索引的开销是很大的。建立以天为单位的缓冲表比较实在;
      

  17.   

    不应该慢,我单位的系统每天要插入10W左右,而且每条记录还附带近1MB的照片
      

  18.   

    先检查程序,将和这个表有有绑定的数据感知控件全部去掉。在估算一个数据的最大量,总不至于每天七万,无限的增加下去吧将条码的长度保存起来,先用条码的长度进行过滤,如果80%以上的长度都是一个长度,则不用这个方法将条码中的偶数个数保存在一个独立的数字字段中,先进行比较,应该先能排除一半将条码的最后几位数据独立保存在一个数字字段中,先进行比较,数字比较速度应该比字段比较快在根据业务看是否能用时间来划分,每天或每周,每月建立一张表增加一int类型的主键。撤销条码的主键。
    总的原则是将数据分类来查,不要每将都在一大堆中查找,就象在书店一样,可以按出版商,按书类型进行
    书架分类,然后找书的时间才能快速定位。
      

  19.   

    在SQL2000中,几百万条数据是不算多的,
    如果产品条码是主键或者有索引的话, 
    查询的速度应该是很快的.
    我做过测试, 在五千万条数据中检索一条(where条件是主键或者是索引,用的是"=")
    时间不会超过几百毫秒.
    你的表是不是索引过多.请确认.
    建议先检索是否存在,然后再插入.
    不会出现那样的问题
      

  20.   

    数据库索引查询快,但会影响插入速度,它有两面性。在内存中实现一个HASH。现在的服务器都四个G以上的内存,每天7万记录没问题。检查时从内存HASH中查询,插入时存到数据库中,按月建表。一个月下来也只有向几千万的记录。
      

  21.   

    1、楼主的应用场景描述不够清晰。
    2、条码建主键索引,使用捕捉sql错误还做程序错误处理,都是正确的。
    分析:
    3、你的数据每天7万,那么按月分表是可以做的。
      检查过你的数据库主机性能没?忙的时候消耗CPU多少、内存多少,是否满足应用需要?
      有多少程序在并发处理这个表,是否有锁表的产生,都要看看。
    4、我在工作中应用的都是千万级以上的数据,并发的用户量很多,当然数据库主机也很强劲(IBM16CPU,32G内存)。你的问题该不难解决。
      

  22.   

    条形码基本对每个商品都是唯一的,也可能一个商品有多个条形码,
    每天7W,也就是7W种商品。
    30天210W,也就是210W种商品。
      

  23.   

    如果其他地方没问题的话
    我认为瓶颈就在比较的过程。
    那么是不是可以这样:1.在做比较的时候统计每一个条形码的重复次数。2.将经常重复的条形码(比如说前20W个)拿出来做
    第一次比较,不重复再进行后续比较。PS: 当然,如果条码的重复数分布很平均的话,这个方法无效。
      

  24.   

    看完了。学习中,幸好没用sqlserver2000搞这种大数据量。
      

  25.   

    1.一秒之内都应该可以接受 
    2.并发输入在30台电脑左右 
    3.数据库服务器的配置志强2.8双核CPU两个,内存2G 
    4. 条码不能重复是指表中任意时期记录的条码都不能重复 
    5. 应用系统是局域网
    可以开sql跟踪,看慢在哪里啊,cpu,IO,哪里慢解决哪里问题
    数据库服务器CPU足够了, 条件允许的话再加2G内存, 硬盘加满;
    如果有6个硬盘1,2硬盘RAID1(操作系统,数据库软件); 3,4,5,6硬盘RAID10; 数据库文件放在RAID10盘上
    如果有8个硬盘1,2硬盘RAID1(操作系统,数据库软件); 3,4硬盘RAID10(数据库使用文件组,放索引文件);
    5,6,7,8硬盘RAID10放数据文件
    操作系统和数据库可以升级到X64版本,数据用sql server 2005或2008版本
    定期做碎片整理及重建索引工作;
    数据记录的表用条码字段做主键,聚集索引,如果要写入快表的索引尽量少.
    是否对表分区看具体应用了,条码字段是全局索引,如果只考虑对条码字段唯一性,分区没什么意义.
    写表使用存储过程.
    你的这种要求insert的sql也能满足,使用绑定变量方法,减少sql的解析时间.