C# 将记录插入数据库的更快方法
所以我现在有一个大约70000个名字的数据库表。我想做的是从该数据库中随机抽取3000条记录,并将它们插入另一个表中,其中每个名称都有一行表示所有其他名称。换句话说,新表应该如下所示: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循环一次添加一行,然后从要添加的名称列表中删除第一个名称,以确保没有顺序不同的重复记录 我的问题是:有没有更快的方
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只是语法,可以调用