简体   繁体   English

MySQL C#插入的性能

[英]MySQL C# performance of Insert

I am developering a application which checks the database on startup (updates for new data) and when work is done(on shutdown/log-off) it pushes the performance logs to the database. 我正在开发一个应用程序,该应用程序会在启动时检查数据库(更新新数据),并在工作完成时(关闭/注销时)将性能日志推送到数据库。 The users themself is not changeing any data, they are only generating logs (the money comes from their use of the data ;) 用户本身并没有改变任何数据,他们只是生成日志(金钱来自他们对数据的使用;)

When the users is done with the work, the application pushes logs to the database(MySQL database), I do not want to constantly push data, due to the connections are expected to drop and go offline doing the work day (mobile work), the less time online the better. 当用户完成工作后,应用程序会将日志推送到数据库(MySQL数据库),我不想一直推送数据,因为在工作日(移动工作),连接会掉线并脱机,在线时间越短越好。 This means the application have to be able to work in offline mode too. 这意味着该应用程序也必须能够在脱机模式下工作。

The log pushed for a single user is usually about 2000 records, and each record contains about 70 bytes of data. 为单个用户推送的日志通常约为2000条记录,每条记录包含约70个字节的数据。 There is about 100 user at peak time (may grow to 300 in the near future) which makes it about 200.000 records of logs which is pushed to the MySQL Database each day. 在高峰时间大约有100个用户(在不久的将来可能增长到300个),这使得它每天大约有200.000条日志记录被推送到MySQL数据库。 Because the users work at the same hours, there is going to be heavy peak times. 因为用户是在同一时间工作,所以高峰时间会很繁重。 Worst case is 200.000 records each of 70 bytes at the same time(~14 mb of data). 最坏的情况是同时70个字节中的每个200.000条记录(〜14 mb数据)。

The database I am using is a MySQL database, this is choosen mostly because: 我使用的数据库是MySQL数据库,之所以选择该数据库,主要是因为:

  • It is free (Sells arguments) 它是免费的(出售参数)
  • I can find help online 我可以在网上找到帮助
  • It is a standard database, means other IT Dept most likely know about it already 它是一个标准数据库,意味着其他IT部门最有可能已经知道它

I am developing the application using: C# .Net 4.5 我正在使用以下程序开发应用程序:C#.Net 4.5

I have tried to use EntityFramework, this is very easy to start with, but it kinda fails on preformance. 我尝试使用EntityFramework,这很容易开始,但是在性能上还是有点失败。 The 2000 logs (inserts) for a single user takes about 7 seconds when I run the program + Server on my developer machine. 当我在开发人员机器上运行程序+服务器时,单个用户的2000日志(插入)大约需要7秒钟。 And 7 seconds is unacceptable (moreover it will proberbly increase dramaticly when 200 users are doing it at the same time) As I have read about it, it appears EntityFramework makes every insert as a single SQL command, and take one SQL Command at a time. 7秒是不可接受的(此外,当200个用户同时执行时,它会急剧增加)据我所知,似乎EntityFramework将每个插入操作都作为一个SQL命令,并且一次使用一个SQL命令。

So I have tried to use MySQL Connector/Net. 因此,我尝试使用MySQL Connector / Net。 But I do not want to do it like EntityFramework, and do each insert as a single command. 但是我不想像EntityFramework那样做,并且每个插入都作为一个命令来完成。 So my eyes went to MySqlBulkLoader. 因此,我的目光投向了MySqlBulkLoader。 But it only want to accept a file, and not raw data, is there a way to load MySqlBulkLoader with data within the program, I would prefer not to save data to the harddisk to be able to send data to the database, it feels like a unnecessary detour. 但是它只想接受一个文件,而不是原始数据,有没有办法在程序中用数据加载MySqlBulkLoader,我宁愿不要将数据保存到硬盘上也可以将数据发送到数据库,感觉就像不必要的弯路。

So my questions is(no more story telling ;) 所以我的问题是(不再讲故事了;)

  • Can I load MySqlBulkLoader with data from memory without creating a file on the disk? 是否可以在不在磁盘上创建文件的情况下用内存中的数据加载MySqlBulkLoader?
  • Should I use MySQL Connector/Net or is there another way I should do it (like raw SQL statements)? 我应该使用MySQL Connector / Net还是其他方法(例如原始SQL语句)?

EDIT: THE ANSWER IS 编辑:答案是

Use MySQL Connector/Net with raw SQL commands, make the insert as a Batch Insert LIKE THIS . 将MySQL Connector / Net与原始SQL命令一起使用,使插入成为批量插入(如THIS THIS)

Suppose the records were 2000000 instead of just 2000. EF, like other ORMs, is designed for ease of coding in normal transaction workloads instead of performance critical intensive workloads. 假设记录是2000000,而不是2000。EF与其他ORM一样,其设计目的是为了便于在常规事务工作负载中进行编码,而不是对性能至关重要的工作负载进行编码。

The answer is simple: if you are not satisfied after you refactor your code to insert all items in a single DB transaction over a single connection (because 7 seconds is really too much for me too unless you close/open connection every time), you should do raw SQL statements in that part of the code and continue using EF in others. 答案很简单:如果在重构代码以通过单个连接将所有项目插入单个DB事务中后不满意(因为7秒钟对我来说确实太多了,除非每次都关闭/打开连接),应该在代码的那部分执行原始SQL语句,并在其他部分继续使用EF。

There is no other way. 没有别的办法了。 Batch processing done right is by plain old SQL. 正确的批处理是通过普通的旧SQL完成的。

And MysqlBulkLoader is made only for file system operation, though the file can be a temporary file 而且MysqlBulkLoader仅用于文件系统操作,尽管该文件可以是临时文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM