我在数据库中有200,000条记录,PK为varchar(50)
我每隔5分钟SELECT COUNT(*) FROM TABLE
如果该结果大于List.Count,则执行
"SELECT * FROM TABLE WHERE PRIMARYKEY NOT IN ( " + myList.ToCSVString() + ")"
我这样做的原因是因为记录是通过另一个进程添加到表中的。
此查询需要很长时间才能运行,我也相信它会抛出一个OutOfMemoryException
有没有更好的方法来实现这个?
由于
答案 0 :(得分:4)
SQL Server有一个解决方案,添加timestamp列,每次触摸表中的任何行时,时间戳都会增长。
为timestamp列添加索引。
而不是仅将id存储在内存中,存储ID和上次时间戳。
更新:
处理删除有点棘手,但如果你使用逻辑删除而不是删除,则可以实现。
答案 1 :(得分:1)
你可以换桌子吗?
如果是这样,您可能需要添加一个新的自动增量列,该列将用作PK TableId
。
在每个SELECT
上保存最大ID,然后在下一个选择中添加TableId > maxId
。
答案 2 :(得分:0)
创建一个INT PK,并使用以下内容:
"SELECT * FROM TABLE WHERE MY_ID > " + myList.Last().Id;
如果您无法更改PK,请创建另一列,其中日期为类型,并使用NOW()作为默认值,并使用它来查询新项目。
答案 3 :(得分:0)
在数据库中创建另一个表,其中一列用于主键。应用程序启动时,将PK插入此表。然后,您可以使用select直接检测添加的键,而不是检查计数:
select PrimaryKey from Table where PrimaryKey not in (select PrimaryKey from OtherTable)
答案 4 :(得分:0)
如果此CSV列表很大,我建议您将文件加载到临时表中,在其上放置索引并在其中执行左连接
select tbl.*
from table tbl
left join #tmpTable tmp on tbl.primarykey = tmp.primarykey
where tmp.primary key is null
编辑:主键不应该是varchar。它应该几乎总是增加int / bigint。这会容易得多。从表中选择*,其中primarykey> @lastknownkey
Smack设计这个的DB程序员..:p
此设计还会导致索引碎片,因为行不会以线性方式插入。