c# - npgsql/PostgreSQL 在 LAN 上的性能非常低

标签 c# postgresql npgsql postgres-9.6

我正在使用 npgsql 检查 Postgresql 准备语句。 它在安装了 Postgresql 服务器的同一台机器上运行完美。 在服务器(同一台机器)上使用简单的 100000 个随机值 INSERT 语句

它在大约 12.16 秒内插入 100k 条记录。 8224条记录/秒 如果没有准备。 它在大约 7.76 秒内插入 100k 条记录。 12886条记录/秒 if 准备语句 Same machine with 127.0.0.1/172.16.16.33 在客户端(同一 LAN 中具有相同 IP 范围和相同配置 8Gb RAM 的另一台机器)

它在大约 89.36 秒内插入 100k 条记录。 1119条记录/秒 如果没有准备。 它在大约 87.95 秒内插入 100k 条记录。 1137 条记录/秒。 如果准备好的声明。 From Another Machine with ip 172.16.16.35 这种 LAN 上的性能是非常 Not Acceptable 。请帮忙。

我已经使用 https://www.pgconfig.org/#/tuning 配置了我的 postgresql 服务器

同时在两台计算机上都禁用了防病毒 + 防火墙。

该表已经是 UNLOGGED 并且没有任何约束或索引。

PostgreSQL 版本 9.6.12


        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled=false; 
            button2.Enabled=false;
            button3.Enabled = false;
            lblUnprepared.Text = "Executing... Please Wait...!";
            lblUnprepared.Refresh();
            npgCmd.CommandText = "TRUNCATE TABLE TBL_ETCBLACKLIST_TEST";
            npgCmd.ExecuteNonQuery();
            procInsertData();
        }

        private void procInsertData()
        {
            string strFileDownloadId = string.Empty;
            string strValues_0 = string.Empty;
            string strValues_1 = string.Empty;
            string strValues_2 = string.Empty;
            string strValues_3 = string.Empty;
            string strBlacklistFileNameWithoutExtension = string.Empty;

            DateTime strDateTime = DateTime.Now;

            DateTime strstarttime= DateTime.Now;


            objLog.Log(0, "Start Executing SQL");
            npgCmd.CommandType = CommandType.Text;
            npgCmd.Connection = npgConn;


            for (int i = 0; i <= lRows; i++)
            {
                //npgCmd = new NpgsqlCommand();
                //NpgsqlDataReader npgRD = null;

                strFileDownloadId = i.ToString();
                strValues_0 = RandomString(10, true) +  i;
                strValues_1 = RandomString(1, true);
                strValues_2 = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss");
                strValues_3 = RandomString(10, true);
                strBlacklistFileNameWithoutExtension = RandomString(10, true);

                strSQL = "INSERT INTO TBL_ETCBLACKLIST_TEST(ETCFileDownload_ID, ETC_Tag_ID, Tag_Status, Effective_Date, "
                   + " Reason_Code, CCHFile_ID, Create_DateTime, Last_Update_Date, CCHBank_ID) VALUES("
                   + strFileDownloadId + ", '" + strValues_0 + "', '" + strValues_1 + "', TO_TIMESTAMP('" + strValues_2 + "','YYYY/MM/DD HH24:MI:SS') "
                   + ", '" + strValues_3 + "', '" + strBlacklistFileNameWithoutExtension + "','" + DateTime.Now +"','" + DateTime.Now + "', 1 )";

                npgCmd.CommandText = strSQL;
              npgCmd.ExecuteNonQuery();
            }
            DateTime strEndTime = DateTime.Now;
            var diffInSeconds = (strEndTime - strstarttime).TotalSeconds;
            var lRecPerSec = Math.Round(lRows / diffInSeconds);
            lblUnprepared.Text = string.Format("UnPrepared SQL Inserted {0} Records In {1} Seconds \n@{2} Records Per Second.", lRows, diffInSeconds, lRecPerSec);

            objLog.Log(0, "UnPrepeared SQL Processed in: " + diffInSeconds); 
            //npgCmd.Dispose();
            //MessageBox.Show(string.Format("UnPreapared Statement Processed in {0} Seconds.", diffInSeconds));
            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;

            //npgRD.Dispose();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string strFileDownloadId = string.Empty;
            string strValues_0 = string.Empty;
            string strValues_1 = string.Empty;
            string strValues_2 = string.Empty;
            string strValues_3 = string.Empty;
            string strBlacklistFileNameWithoutExtension = string.Empty;

            DateTime strDateTime = DateTime.Now;
            DateTime strstarttime = DateTime.Now;

            button1.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;

    npgCmd.CommandText = "TRUNCATE TABLE TBL_ETCBLACKLIST_TEST";
            npgCmd.ExecuteNonQuery();

            objLog.Log(0, "Start Executing SQL");
            lblPrepared.Text = "Executing... Please Wait...!";
            lblPrepared.Refresh();

            strSQL = "INSERT INTO TBL_ETCBLACKLIST_TEST(ETCFileDownload_ID, ETC_Tag_ID, Tag_Status, Effective_Date, "
               + " Reason_Code, CCHFile_ID, Create_DateTime, Last_Update_Date, CCHBank_ID) VALUES("
               + "@Param1 , @Param2,@Param3,@Param4,@Param5,@Param6,@Param7,@Param8,@Param9)";

            npgCmd.CommandText = strSQL;
            npgCmd.CommandType = CommandType.Text;
            npgCmd.Connection = npgConn;

            npgCmd.Parameters.Add("@Param1", NpgsqlDbType.Numeric);

            npgCmd.Parameters.Add("@Param2", NpgsqlDbType.Text);
            npgCmd.Parameters.Add("@Param3", NpgsqlDbType.Text);
            npgCmd.Parameters.Add("@Param4", NpgsqlDbType.Date);
            npgCmd.Parameters.Add("@Param5", NpgsqlDbType.Text);
            npgCmd.Parameters.Add("@Param6", NpgsqlDbType.Text);
            npgCmd.Parameters.Add("@Param7", NpgsqlDbType.Date);
            npgCmd.Parameters.Add("@Param8", NpgsqlDbType.Date);
            npgCmd.Parameters.Add("@Param9", NpgsqlDbType.Numeric);
            npgCmd.Prepare();

            for (int i = 0; i <= lRows; i++)
            {
//                npgCmd = new NpgsqlCommand();

                strFileDownloadId = i.ToString();
                strValues_0 = RandomString(10, true) + i;
                strValues_1 = RandomString(1, true);
                strValues_2 = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss");
                strValues_3 = RandomString(10, true);
                strBlacklistFileNameWithoutExtension = RandomString(10, true);
                npgCmd.Parameters[0].Value = strFileDownloadId;
                npgCmd.Parameters[1].Value = strValues_0;
                npgCmd.Parameters[2].Value = strValues_1;
                npgCmd.Parameters[3].Value = strValues_2;
                npgCmd.Parameters[4].Value = strValues_3;
                npgCmd.Parameters[5].Value = strBlacklistFileNameWithoutExtension;
                npgCmd.Parameters[6].Value = DateTime.Now;
                npgCmd.Parameters[7].Value = DateTime.Now;
                npgCmd.Parameters[8].Value = 1;

                npgCmd.ExecuteNonQuery();
            }
            DateTime strEndTime = DateTime.Now;

            var diffInSeconds = (strEndTime - strstarttime).TotalSeconds;
            var lRecPerSec = Math.Round(lRows / diffInSeconds);

            lblPrepared.Text = string.Format("Prepared SQL Inserted {0} Records In {1} Seconds \n@ {2} Records Per Second.", lRows, diffInSeconds, lRecPerSec);
            //MessageBox.Show(string.Format("Preapared SQL Processed in {0} Seconds.", diffInSeconds));
            objLog.Log(0, "Prepeared SQL Processed in: " + diffInSeconds);

            lblPrepared.Text = string.Format("Prepared SQL Inserted {0} Records In {1} Seconds \n@ {2} Records Per Second.", lRows, diffInSeconds, lRecPerSec);
            //MessageBox.Show(string.Format("Preapared SQL Processed in {0} Seconds.", diffInSeconds));
            objLog.Log(0, "Prepeared SQL Processed in: " + diffInSeconds);

            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;

            //Cant find npgsql.Unprepare();
            //npgCmd.Dispose();
            //npgRD.Dispose();
        }

postgresql.auto.conf 如下。

shared_buffers = '512MB'
effective_cache_size = '6GB'
work_mem = '82MB'
maintenance_work_mem = '512MB'
min_wal_size = '512MB'
max_wal_size = '2GB'
checkpoint_completion_target = '0.7'
wal_buffers = '16MB'
listen_addresses = '*'
max_connections = '100'
random_page_cost = '4.0'
logging_collector = 'on'
log_checkpoints = 'on'
log_connections = 'on'
log_disconnections = 'on'
log_lock_waits = 'on'
log_temp_files = '0'
lc_messages = 'C'
log_min_duration_statement = '10s'
log_autovacuum_min_duration = '0'
log_destination = 'stderr'
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

最佳答案

如@felice-pollano 上面所写,您可能想查看 Npgsql's bulk copy support ,它允许您在单次往返中插入大量数据。它往往比简单的插入更优化。

如果您对每个 SQL 执行一次往返,那么与本地主机相比,您会发现 LAN 上的性能大幅下降是有道理的。在后者中几乎没有延迟,但在前者中,您花费大部分时间等待协议(protocol)消息到达 PostgreSQL 并返回。

关于c# - npgsql/PostgreSQL 在 LAN 上的性能非常低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56000163/

相关文章:

c# - 在 C# .NET 中,如何读取具有基于 ascii 的专有编码的文本文件

c# - Paypal Windows 8 结帐 SDK

unit-testing - NHibernate/Npgsql 在调试 UnitTest 时在 CreateSchema 期间抛出异常

django - 我如何更新一个 PostgreSQL 数据库并将更改/更新同步到另一台服务器上的另一个 PostgreSQL 数据库

node.js - SequelizeDatabaseError - 缺少列 - 一对多关联

C# with Npgsql - 无法使用处理程序类型 Int32Handler 编写 CLR 类型 System.String

c# - 一起使用 npgsql 12 和 ef 6 - 有人成功了吗?

c# - 如何在 WinForms 的 ComboBox 中居中对齐所选项目?

c# - 如何在 dev .net 6 上的项目中检索环境变量

sql - 从特定列中查找小数位数