C# 在不迭代的情况下检索所有ID?
我的SQLite数据库中有一个表,其中有将近200万条记录,有些记录的生日为空,我想用antoher数据库中的数据进行修复,因为这两个表上的ID都是相同的,我可以在这次更新中引用它 然而,我有一个阅读的问题,我相信我会有她的更新 读取问题,是否有一种方法可以从结果中获取所有ID,而不必逐个读取 正在执行的查询是(已编制索引): 目前,我这样做是为了检索所有ID(第一个300k记录大约需要3分钟,然后对于250k记录增加到大约9分钟,并不断增加延迟): 在我将重用ids列表来执行对每个记录的更新,更新的日期是正确的,我认为我将遇到相同的问题,通过插入1到1将需要很长时间,这将使我们看到我认为是第二个问题 有没有一种快速的方法用所需的数据更新所有记录 注意:我为更新SQLITE而阅读的生日将来自远程MySQL服务器,因此我无法链接更新选择等二合一查询。 表格格式为:C# 在不迭代的情况下检索所有ID?,c#,sqlite,.net-4.0,C#,Sqlite,.net 4.0,我的SQLite数据库中有一个表,其中有将近200万条记录,有些记录的生日为空,我想用antoher数据库中的数据进行修复,因为这两个表上的ID都是相同的,我可以在这次更新中引用它 然而,我有一个阅读的问题,我相信我会有她的更新 读取问题,是否有一种方法可以从结果中获取所有ID,而不必逐个读取 正在执行的查询是(已编制索引): 目前,我这样做是为了检索所有ID(第一个300k记录大约需要3分钟,然后对于250k记录增加到大约9分钟,并不断增加延迟): 在我将重用ids列表来执行对每个记录的更新,
id
first_name
last_name
birthday
email
status
当我在SQLite Admin上运行同一个查询时,吐出所有数据需要2371ms,因此我假设我一定是读错了,或者一个接一个的读取肯定会对它造成很大的伤害。您可以尝试使用读取数据表
或数据集
中的所有数据
我不确定这是否会更快,但可能值得一试
假设您有一个名为cmd
的DbCommand
实例,代码可能是:
var table = new DataTable();
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(table);
(我认为您必须使用SqliteDataAdapter—我不知道SQLite的确切名称)
在此之后,表
应该有一列并包含您需要的所有数据
如果速度仍然缓慢,我会尝试其他方法:
- 分批处理数据(例如,根据主键id,一次处理100或1000个项目)
- 如果可能的话,尽量不使用C#(例如,在MySQL中进行数据导入,在那里使用
运行JOIN
,然后将数据带回SQLite)UPDATE
数据表
或数据集
中的所有数据
我不确定这是否会更快,但可能值得一试
假设您有一个名为cmd
的DbCommand
实例,代码可能是:
var table = new DataTable();
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(table);
(我认为您必须使用SqliteDataAdapter—我不知道SQLite的确切名称)
在此之后,表
应该有一列并包含您需要的所有数据
如果速度仍然缓慢,我会尝试其他方法:
- 分批处理数据(例如,根据主键id,一次处理100或1000个项目)
- 如果可能的话,尽量不使用C#(例如,在MySQL中进行数据导入,在那里使用
运行JOIN
,然后将数据带回SQLite)UPDATE
UPDATE
Persons
SET
Persons.birthday = OtherTable.birthday
FROM
Persons
INNER JOIN
OtherTable
ON
Persons.ID = OtherTable.ID
WHERE
Persons.birthday IS NULL OR Persons.birthday = ''
在数据库上执行此SQL。不需要遍历所有记录。它可以在一个动作中满足您的所有需求:
UPDATE
Persons
SET
Persons.birthday = OtherTable.birthday
FROM
Persons
INNER JOIN
OtherTable
ON
Persons.ID = OtherTable.ID
WHERE
Persons.birthday IS NULL OR Persons.birthday = ''
您可以在一次调用中检索数据集中的所有行
using (SqlConnection cnn = new SqlConnection("connection_string_here"))
{
SqlDataAdapter da = new SqlDataAdapter("SELECT id FROM personal
WHERE birthday IS NULL OR birthday = ''", cnn);
DataSet ds = new DataSet();
da.Fill(ds, "personal");
List<string> pids = new List<string>();
foreach(DataRow row in ds.Tables["personal"].Rows)
{
pids.Add(row["id"].ToString());
// similarly you can update row objects here.
}
}
使用(SqlConnection cnn=newsqlconnection(“connection\u string\u here”))
{
SqlDataAdapter da=新建SqlDataAdapter(“从个人数据库中选择id
其中生日为空或生日为“”,cnn);
数据集ds=新数据集();
da.填写(ds,“个人”);
List pids=新列表();
foreach(ds.Tables[“personal”].Rows中的数据行)
{
添加(行[“id”].ToString());
//类似地,您可以在此处更新行对象。
}
}
在数据集中执行更新,然后使用数据集对象保存更改
您可以在一次调用中检索数据集中的所有行
using (SqlConnection cnn = new SqlConnection("connection_string_here"))
{
SqlDataAdapter da = new SqlDataAdapter("SELECT id FROM personal
WHERE birthday IS NULL OR birthday = ''", cnn);
DataSet ds = new DataSet();
da.Fill(ds, "personal");
List<string> pids = new List<string>();
foreach(DataRow row in ds.Tables["personal"].Rows)
{
pids.Add(row["id"].ToString());
// similarly you can update row objects here.
}
}
使用(SqlConnection cnn=newsqlconnection(“connection\u string\u here”))
{
SqlDataAdapter da=新建SqlDataAdapter(“从个人数据库中选择id
其中生日为空或生日为“”,cnn);
数据集ds=新数据集();
da.填写(ds,“个人”);
List pids=新列表();
foreach(ds.Tables[“personal”].Rows中的数据行)
{
添加(行[“id”].ToString());
//类似地,您可以在此处更新行对象。
}
}
在数据集中执行更新,然后使用数据集对象保存更改
您可以使用以逗号分隔的字符串检索ID列表,然后将其拆分为整数数组。比如:
从生日为空或生日为“”的个人中选择GROUP_CONCAT(id)
然后在代码中执行以下操作:
var ids = myStringOfIDs.Split(',').Select(val => int.Parse(val));
对于更新,一种方法是这样做。您可以使用以逗号分隔的字符串检索ID列表,然后将其拆分为整数数组。比如:
从生日为空或生日为“”的个人中选择GROUP_CONCAT(id)
然后在代码中执行以下操作:
var ids = myStringOfIDs.Split(',').Select(val => int.Parse(val));
对于更新,一种方法是这样做。这可能与sqlite有关-转换器工具可能会有所帮助。这并不重要,因为lboshuizen+Bader的答案,但读取ID变慢的原因是必须重复调整ID的大小。您可以先执行
SELECT COUNT(*)…
并将ids
预分配到该大小来加速此过程。这可能与sqlite有关-转换器工具可能会有所帮助这并不重要,因为lboshuizen+Bader的答案,但读取ids会变慢的原因是ids
必须重复调整大小。你可以加快速度