Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.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#_Ado.net_Bigdata_Datareader_Dataadapter - Fatal编程技术网

C# 有没有直接的方法可以将数据加载到内存中,而不必加载到数据库服务器上?

C# 有没有直接的方法可以将数据加载到内存中,而不必加载到数据库服务器上?,c#,ado.net,bigdata,datareader,dataadapter,C#,Ado.net,Bigdata,Datareader,Dataadapter,我正在尝试从sql server和oracle rdbms读取数百万数据 Sql Server - select Id as LinkedColumn,CompareColumn from Source order by LinkedColumn Oracle -select Id as LinkedColumn,CompareColumn from Target order by LinkedColumn 此数据库位于不同的服务器上,我想从不同的服务器读取此数据 所以,我们的想法是尽可能让数

我正在尝试从sql server和oracle rdbms读取数百万数据

Sql Server - select Id as LinkedColumn,CompareColumn from Source order by LinkedColumn
Oracle -select Id as LinkedColumn,CompareColumn from Target order by LinkedColumn
此数据库位于不同的服务器上,我想从不同的服务器读取此数据

所以,我们的想法是尽可能让数据库服务器保持空闲

我正在考虑将这数百万数据分块读取,而不是使用data reader读取数据,data reader将在数据库上执行整个查询,数据库服务器将在内存流中打开这些记录,data reader将从中读取这些记录

由于数据库服务器上的负载,当存在多个作业时,这将花费大量时间

Records in Source : 12377200

Records in Target : 12266800
因为这个订单,它花费了太多的时间

那个么,有并没有任何方法可以在数据库上执行查询,并以某种方式将数据直接放入我的服务器内存(
datatable或list或array
等),而无需在数据库服务器上加载

我下面的代码占用了2400万条记录太多的时间(仅从源和目标读取数据就超过2小时)

代码:

public void Test(SqlConnection srcCon, SqlConnection tgtCon)
        {
            int srcChunkSize = 1000;
            int srcCurCount = 1;
            int tgtChunkSize = 1000;
            int tgtCurCount = 1;
            bool srcBreak = false;
            bool tgtBreak = false;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            var da1 = new SqlDataAdapter(null, srcCon);
            var da2 = new SqlDataAdapter(null, tgtCon);
            da1.SelectCommand.CommandTimeout = 0;
            da2.SelectCommand.CommandTimeout = 0;
            while (true)
            {
                var srcDt = new DataTable();
                var tgtDt = new DataTable();
                if (!srcBreak)
                {
                    string srcQuery = "select Id as LinkedColumn,CompareColumn from Source order by LinkedColumn" +
                                        " OFFSET ((" + srcCurCount + " - 1) * " + srcChunkSize + " ) ROWS FETCH NEXT " + srcChunkSize + " ROWS ONLY;";
                    da1.SelectCommand.CommandText = srcQuery;
                    srcDt = GetDatatable(da1);
                }
                if (!tgtBreak)
                {
                    string tgtQuery = "select Id as LinkedColumn,CompareColumn from Target order by LinkedColumn" +
                                        " OFFSET ((" + tgtCurCount + " - 1) * " + tgtChunkSize + " ) ROWS FETCH NEXT " + tgtChunkSize + " ROWS ONLY;";
                    da2.SelectCommand.CommandText = tgtQuery;
                    tgtDt = GetDatatable(da2);
                }

                if (srcDt.Rows.Count == 0) srcBreak = true;
                srcCurCount++;

                if (tgtDt.Rows.Count == 0) tgtBreak = true;
                tgtCurCount++;

                if (srcBreak && tgtBreak) break;
            }
            stopwatch.Stop();
            string a = stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss");
            Console.WriteLine(a);
        }

        private DataTable GetDatatable(SqlDataAdapter da)
        {
            DataTable dt = new DataTable();
            da.Fill(dt);
            return dt;
        }

在不知道自己的最终目标是什么的情况下,很难给出一个好的答案。例如,最好的答案可能是在存储过程中而不是在c#中执行任务

然而,为了简单地加快进程,您可以使用并行编程。这里有一个很好的起点:

也请考虑后退一步,看看你的体系结构。您可能会从旋转图形数据库和从Oracle执行批导出\导入中获益。图形数据库在复杂的海量关系查询中效率更高。

SqlDataReader:

保持连接打开直到我们完成(不要忘记关闭它!)。 通常只能迭代一次 对于更新回数据库没有那么有用 另一方面,它: 一次内存中只有一条记录,而不是整个结果集(这可能是巨大的) 大约是我们在那一次迭代中所能达到的最快速度 允许我们更快地开始处理结果(一旦第一条记录可用)

SqlDataAdapter/DataSet

让我们在加载数据后立即关闭连接,甚至可以为我们自动关闭连接 所有结果都在内存中可用 我们可以根据需要对它进行多次迭代,甚至可以通过索引查找特定记录 有一些内置的功能,可以更新回数据库 代价是: 更高的内存使用率 在使用任何数据之前,我们都会等待所有数据加载完毕

您可以在以下网址查看原始帖子:


谢谢。

那么你是说我应该使用导出数据到图形数据库,然后使用图形数据库中的数据做任何我想做的事情吗?是的。看看Neo4j,我不知道如何一下子把整个东西读入内存(你现在正在做什么)与使用datareader逐个读取相比,将在数据库上施加更少的负载。@数据读取器的Evk问题是,当我在数据库流中执行executereader时,结果集将被维护并逐1读取,所以在我读取完整个结果集之前,负载一直在数据库服务器上。如果我错了,请纠正我。您的1000条记录的块太多了小的确保这些表上的索引涵盖了选定的列-索引应位于
Id
列上,并包括
CompareColumn
@ZoharPeled虽然我在Id列上有索引,但花费的时间太多了。那么,您建议块大小是多少?对于1230万条记录,我建议至少有100000条记录作为缓冲区。选择1000条记录意味着您必须运行select语句12300次。。。