Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将记录插入数据库的更快方法_C#_Sql_Sql Server_Parallel.foreach - Fatal编程技术网

C# 将记录插入数据库的更快方法

C# 将记录插入数据库的更快方法,c#,sql,sql-server,parallel.foreach,C#,Sql,Sql Server,Parallel.foreach,所以我现在有一个大约70000个名字的数据库表。我想做的是从该数据库中随机抽取3000条记录,并将它们插入另一个表中,其中每个名称都有一行表示所有其他名称。换句话说,新表应该如下所示: John, jerry john, alex john, sam jerry, alex jerry, sam alex, sam 这意味着我应该向表中添加n行总和。我目前的策略是使用两个嵌套for循环一次添加一行,然后从要添加的名称列表中删除第一个名称,以确保没有顺序不同的重复记录 我的问题是:有没有更快的方

所以我现在有一个大约70000个名字的数据库表。我想做的是从该数据库中随机抽取3000条记录,并将它们插入另一个表中,其中每个名称都有一行表示所有其他名称。换句话说,新表应该如下所示:

John, jerry
john, alex
john, sam
jerry, alex
jerry, sam
alex, sam
这意味着我应该向表中添加n行总和。我目前的策略是使用两个嵌套for循环一次添加一行,然后从要添加的名称列表中删除第一个名称,以确保没有顺序不同的重复记录


我的问题是:有没有更快的方法来实现这一点,可能是通过并行for循环或PLINQ或其他一些我没有提到的选项?

您需要找出随机部分

select t1.name, t2.name 
from table t1 
join table t2 
on t1.name < t2.name 
order by t1.name, t2.name
选择t1.name,t2.name
来自表t1
联接表t2
关于t1.name
你需要具体化newid

declare @t table (name varchar(10) primary key);
insert into @t (name) values 
       ('Adam')
     , ('Bob')
     , ('Charlie')
     , ('Den')
     , ('Eric')
     , ('Fred');
declare @top table (name varchar(10) primary key);
insert into @top (name)
select top (4) name from @t order by NEWID();

select * from @top;

select a.name, b.name
from @top a  
join @top b 
  on a.name < b.name  
order by a.name, b.name;
declare@t表(name varchar(10)主键);
插入到@t(name)值中
(“亚当”)
,(“鲍勃”)
,(“查理”)
,(‘Den’)
,(“埃里克”)
,(“弗雷德”);
声明@top表(名称varchar(10)主键);
插入@top(名称)
从@t order by NEWID()中选择顶部(4)名称;
从@top中选择*;
选择a.name,b.name
来自@TopA
加入@TopB
关于a.name
您需要找出随机部分

select t1.name, t2.name 
from table t1 
join table t2 
on t1.name < t2.name 
order by t1.name, t2.name
选择t1.name,t2.name
来自表t1
联接表t2
关于t1.name
你需要具体化newid

declare @t table (name varchar(10) primary key);
insert into @t (name) values 
       ('Adam')
     , ('Bob')
     , ('Charlie')
     , ('Den')
     , ('Eric')
     , ('Fred');
declare @top table (name varchar(10) primary key);
insert into @top (name)
select top (4) name from @t order by NEWID();

select * from @top;

select a.name, b.name
from @top a  
join @top b 
  on a.name < b.name  
order by a.name, b.name;
declare@t表(name varchar(10)主键);
插入到@t(name)值中
(“亚当”)
,(“鲍勃”)
,(“查理”)
,(‘Den’)
,(“埃里克”)
,(“弗雷德”);
声明@top表(名称varchar(10)主键);
插入@top(名称)
从@t order by NEWID()中选择顶部(4)名称;
从@top中选择*;
选择a.name,b.name
来自@TopA
加入@TopB
关于a.name
给定一个表“名称”,其中包含一个nvarchar(50)列“名称”,其中包含以下数据:

Adam
Bob
Charlie
Den
Eric
Fred
此查询:

-- Work out the fraction we need
DECLARE @frac AS float;
SELECT @frac = CAST(35000 AS float) / 70000;

-- Get roughly that sample size
WITH ts AS (
SELECT Name FROM Names
WHERE @frac >= CAST(CHECKSUM(NEWID(), Name) & 0x7FFFFFFF AS float) / CAST (0X7FFFFFFF AS int)
)

-- Match each entry in the sample with all the other entries
SELECT x.Name + ', ' + y.Name
FROM ts AS X
CROSS JOIN
Names AS Y
WHERE x.Name <> y.Name
结果将因运行而异;70000个样本中的3000个样本将有大约3000*70000个结果行。我使用了35000./70000,因为我使用的样本量只有6个

如果只需要使用示例中的名称,请将
交叉连接名称更改为Y
交叉连接ts为Y
,然后将有大约3000*3000个结果行

参考:随机抽样方法取自中的“重要”一节。

给定一个表“名称”,表中有nvarchar(50)列“名称”,数据如下:

Adam
Bob
Charlie
Den
Eric
Fred
此查询:

-- Work out the fraction we need
DECLARE @frac AS float;
SELECT @frac = CAST(35000 AS float) / 70000;

-- Get roughly that sample size
WITH ts AS (
SELECT Name FROM Names
WHERE @frac >= CAST(CHECKSUM(NEWID(), Name) & 0x7FFFFFFF AS float) / CAST (0X7FFFFFFF AS int)
)

-- Match each entry in the sample with all the other entries
SELECT x.Name + ', ' + y.Name
FROM ts AS X
CROSS JOIN
Names AS Y
WHERE x.Name <> y.Name
结果将因运行而异;70000个样本中的3000个样本将有大约3000*70000个结果行。我使用了35000./70000,因为我使用的样本量只有6个

如果只需要使用示例中的名称,请将
交叉连接名称更改为Y
交叉连接ts为Y
,然后将有大约3000*3000个结果行


参考:随机抽样方法取自。

中的“重要”部分,使用数字表模拟名称

单个查询,使用三角形联接

WITH all_names 
     AS (SELECT n, 
                'NAME_' + Cast(n AS VARCHAR(20)) NAME 
         FROM   number 
         WHERE  n < 70000), 
     rand_names 
     AS (SELECT TOP 3000 * 
         FROM   all_names 
         ORDER  BY Newid()), 
     ordered_names 
     AS (SELECT Row_number() 
                  OVER ( 
                    ORDER BY NAME) rw_num, 
                NAME 
         FROM   rand_names) 
SELECT n1.NAME, 
       n2.NAME 
FROM   ordered_names n1 
       INNER JOIN ordered_names n2 
               ON n2.rw_num > n1.rw_num   
与所有_名称
AS(选择n,
'NAME_u'+Cast(n作为VARCHAR(20))名称
从数字
其中n<70000),
兰杜名字
AS(选择前3000名*
从所有的名字
ORDER BY Newid()),
有序名称
AS(选择行号()
超过(
按名称排序)rw_num,
名称
来自rand_名称)
选择n1.NAME,
n2.名称
从有序名称n1
内部联接有序_名称n2
在n2.rw_num>n1.rw_num上

使用数字表模拟名称

单个查询,使用三角形联接

WITH all_names 
     AS (SELECT n, 
                'NAME_' + Cast(n AS VARCHAR(20)) NAME 
         FROM   number 
         WHERE  n < 70000), 
     rand_names 
     AS (SELECT TOP 3000 * 
         FROM   all_names 
         ORDER  BY Newid()), 
     ordered_names 
     AS (SELECT Row_number() 
                  OVER ( 
                    ORDER BY NAME) rw_num, 
                NAME 
         FROM   rand_names) 
SELECT n1.NAME, 
       n2.NAME 
FROM   ordered_names n1 
       INNER JOIN ordered_names n2 
               ON n2.rw_num > n1.rw_num   
与所有_名称
AS(选择n,
'NAME_u'+Cast(n作为VARCHAR(20))名称
从数字
其中n<70000),
兰杜名字
AS(选择前3000名*
从所有的名字
ORDER BY Newid()),
有序名称
AS(选择行号()
超过(
按名称排序)rw_num,
名称
来自rand_名称)
选择n1.NAME,
n2.名称
从有序名称n1
内部联接有序_名称n2
在n2.rw_num>n1.rw_num上


您的数据库是关系型设计吗?您听说过操作吗?交叉连接。不要使用循环。那不是n!。3000! 你的数据库是关系型设计吗?你听说过操作吗?交叉连接。不要使用循环。那不是n!。3000! 我的坏@MartinSmith
按t1.name
排序?
按t1.name
排序?您有重复项。参见OP的样本输出。@Paparazzi更希望OP的样本输出不是他们想要的,他们对输出的描述是正确的。让我们拭目以待吧:)@狗仔队啊,我明白你的意思了。我已经要求OP澄清问题的另一部分。@狗仔队如果是这样的话,欢迎你从这个答案中提取随机样本代码,并将其弹出到你的答案中,这样我就可以删除这个。酷,我发布了另一条消息,你有重复的。参见OP的样本输出。@Paparazzi更希望OP的样本输出不是他们想要的,他们对输出的描述是正确的。让我们拭目以待吧:)@狗仔队啊,我明白你的意思了。我已经要求OP澄清问题的另一部分。@狗仔队如果是这样的话,欢迎你从这个答案中提取随机样本代码,并将其弹出到你的答案中,这样我就可以删除这个。酷,我发布了另一条消息。你测试过这个吗?CTE只是语法,可以调用