如何在C#中处理大量数据与MySQL查询?

问题描述 投票:-1回答:1

我在MySQL中有大量的数据,正好是10180行,而且它每天都在更新200-300行。在我的C#应用程序中,我有一个背景工作程序,它得到的数据和加载到一个datatable,然后这个datatable加载到一个ListView显示数据。

问题是这需要大约1分钟的时间,这在生产中太长了,我想解决这个问题并优化代码。

DoWork方法里面的代码。

            try
        {
            connection.Close();

            if (lvValidate.InvokeRequired)
            {

                lvValidate.BeginInvoke(new MethodInvoker(delegate
                {

                    lvValidate.Items.Clear();
                }));
            }
            else
            {
                lvValidate.Items.Clear();
            }

            System.Data.DataTable dt = DataTransferDA("SELECT * FROM workhours ORDER BY ID desc");

            foreach (System.Data.DataRow row in dt.Rows)
            {
                    ListViewItem tempLv = new ListViewItem(row["ID"].ToString());
                    tempLv.SubItems.Add(row["Date"].ToString());
                    tempLv.SubItems.Add(row["Name"].ToString());
                    tempLv.SubItems.Add(row["WorkCode"].ToString());
                    tempLv.SubItems.Add(row["Assembly"].ToString());
                    tempLv.SubItems.Add(row["Tech"].ToString());
                    tempLv.SubItems.Add(row["Beginning"].ToString());
                    tempLv.SubItems.Add(row["Ending"].ToString());
                    tempLv.SubItems.Add(row["Validated"].ToString());
                    tempLv.SubItems.Add(row["Validated name"].ToString());
                lvValidate.BeginInvoke(new MethodInvoker(delegate
                {
                    lvValidate.Items.Add(tempLv);
                }));


            }
            if (lvValidate.InvokeRequired)
            {

                lvValidate.BeginInvoke(new MethodInvoker(delegate
                {
                    lvValidate.TopItem = lvValidate.Items[topIndex];
                }));
            }
            else
            {
                lvValidate.TopItem = lvValidate.Items[topIndex];
            }
            connection.Close();
        }
        catch (Exception ex) { MessageBox.Show("Error happened: " + ex.Message); connection.Close();} }
c# mysql .net large-data
1个回答
0
投票

如果我不得不猜测它的列表视图是导致问题比数据大小。

我在一个有50284行的数据库上做了一个小测试。当我使用列表视图时,它花了很长时间才显示出来,我的笔记本风扇被踢到了全倾斜,即使通过数据迭代只花了876ms。 我把测试表单换成了一个基本的listbox,在构造函数中加载数据后,只花了几秒钟就显示出来了。

我使用EFCore来做数据连接处理,但我不能认为这造成了原始查询的性能的巨大变化。

数据(50284)花了876

            int i = 0;
            using (EFContext ctx = new EFContext())
            {
                foreach(data dt in ctx.data.AsNoTracking())
                {
                    i++;
                    listBox.Items.Add(dt.epc);
                }
            }
            watch.Stop();
            System.Diagnostics.Debug.WriteLine($"Data({i}) took {watch.ElapsedMilliseconds}");

编辑]EFContext是一个Entity Framework Core组件,但它所做的只是包裹数据库模型。 我追踪了一下,它只是和你一样发出了一个select blah from db.table。它只是把数据以类的形式保存下来,所以你可以像正常的代码一样进行迭代和交互。

我目前是在Entity Framework模式下,并且有这个测试所需的所有模拟代码,否则我会做一个基本的SQL连接。 在这个问题上,查看器是问题,而不是数据大小。


1
投票

一些建议

  1. 对datarow使用整数索引。整数索引可以是 快3-4倍. 在你的循环中,你每行要查找10次列的索引,在循环外查找一次列的位置,然后在循环内使用整数索引。在循环外查找一次列的位置,然后在循环内使用整数索引。

    intDateCol = dt.Columns.IndexOf("Date");...SubItems.Add(row[intDateCol])。

  2. 在清除项目并添加它们之前使用ListView.BeginUpdate(),然后在完成后调用ListView.EndUpdate()。

  3. 如果你仍然有性能问题,请尝试在你的应用程序中使用ListView.BeginUpdate()。虚拟模式.

有一个深入的看ListView的性能调整。此处

© www.soinside.com 2019 - 2024. All rights reserved.