最近在开发中才发现的一个问题,用C 或者C++语言通过编程形式操作 远程的MySQL 数据库,(数据库放在一个空间中)它的效率都很低,测试:插入5000条(只有三个属性 code varchar(20) username(20) address(40))这样的数据,不管是通过MyODBC(5.1)还是通过 MySQL C API 的编程形式操作数据库都得花上 500 多秒,汗死我了,正常的通过JDBC访问的话也只需要5秒左右的,这个测试在 Mysql 5.0 和 MySQL 5.5都测试过,也都分别以 MyODBC 和 MySQL C API 的形式测试过,结果都是差不多的都在130 - 150秒之间徘徊,那位高手曾今遇到过这个问题了。或者懂得怎么解决的。。请发表一下见解,(最后我想说,不会是语句的问题的:测试语句就是一句 Insert Into tablename(xxx,xxx,xxx) vulues('xx','xxxx','xxxx') 插入语句,这个插入语句至于一个 for(int i=0;i<5000;i++) 中,所以不要考虑是编写代码的问题了。。代码就简单的插入语句。请高手们指点谢谢由于昨天高手wwwwa的方法 在 insert into 操作前加入 BeginTransaction() insert into ...
commitTransaction() 这对本地的数据库是起作用了。。但是远程的MySQL数据库,插入操作还是很慢,(500秒啊)不要考虑这个网络问题了网络再怎么的慢也不会有500秒那么夸张的,,那位高手。。请再指点指点
commitTransaction() 这对本地的数据库是起作用了。。但是远程的MySQL数据库,插入操作还是很慢,(500秒啊)不要考虑这个网络问题了网络再怎么的慢也不会有500秒那么夸张的,,那位高手。。请再指点指点
就加上skip-name-resolve
id int auto_increment,
code varchar(20) not null,
username varchar(20) not null,
address varchar(40) not null,
constraint pk_testcode primary key(id));
我想在建表的时候指定数据表所用的的数据库引擎,InnoDB 这样会不会好些呢?
回复:trainee:
if(db.Open(strConnection))
{
TRY
{
db.BeginTransaction();
CString sql("");
sql="insert into tba_test(code,username) Values('sdfdsfdsfdssdfsd','张三家')";
db.Execute(sql);
db.CommitTransaction();
db.Close();
}
CATCH(CFileException,e)
{
return;
}
}如果是把数据库连接也算进去的话,单次插入时间为 3.23秒,经测试数据连接时间为2.5秒左右,不包括数据库连接时间单次插入如果用事务的话每次都基本在 1 秒左右,不用事务就在0.2秒那样子,(可能是网咯问题,也出现过0.02秒的)
我想这根本就是数据引擎问题,等我把在建表的时候把数据库引擎指定一下,再告诉大家答案,还有一个问题:
就是 skip-name-resolve 加载My.ini的任意位置都可以么?以后回帖子,写得详细些。。谢谢(毕竟大牛们面对的都是我们这些。。菜鸟呀。。哈哈)。。thanks
详细请看msdn!
代码可优化的地方:使用动态bind列值
CADODatabase db;
CString temp("");
CString strConnection = _T("Driver={MySQL ODBC 5.1 Driver};Server=myRemoteServeripcom;Database=mydb;User=username;Password=123456;Option=3");
double timeTol; // 总共消耗的时间
int64 timeStart = 0; // 开始操作时的时间
__int64 timeStop;
SYSTEMTIME systemtime;//记录执行SQL语句前的时间
if(db.Open(strConnection))
{
TRY
{
GetLocalTime(&systemtime);
SystemTimeToFileTime(&systemtime, (FILETIME*)&timeStart);
db.BeginTransaction();
CString sql("");
sql="insert into tba_test(code,username,address) Values('sdfdsfdsfdssdfsd','张三家','宿舍对方立即离开')";
for(int i=0;i<5000;i++)
db.Execute(sql);
db.CommitTransaction();
db.Close();
}
CATCH(CFileException,e)
{
return;
}
END_CATCH
}
//记录执行SQL语句后的时间
GetLocalTime(&systemtime);
SystemTimeToFileTime(&systemtime, (FILETIME*)&timeStop);
//记录执行SQL语句总共消耗的时间
timeTotal = ((double)(timeStop - timeStart) / 10000000);
temp.Format("执行远程SQL语句成功\r\n\r\n总共消耗 = %8.3f秒",timeTotal);
MessageBox(temp);
用的CADODatabase 的一个别人封装好的数据库操作类,(个人已经排除了是这个类导致数据库访问效率低下的问题) “ACMAIN_CHM” 还有什么不够详细的么?有更好的想法随时欢迎留言
+---------+---------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------------------------------------------------+
| Table | Create Table |
+---------+---------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------------------------------------------------+
| tb_test | CREATE TABLE `tb_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(20) NOT NULL,
`username` varchar(20) NOT NULL,
`address` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------+---------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> insert into tba_test(code,username) Values('sdfdsfdsfdssdfsd','XXXXxxxx')
;
ERROR 1146 (42S02): Table 'csdn.tba_test' doesn't exist
mysql> insert into tb_test(code,username) Values('sdfdsfdsfdssdfsd','XXXXxxxx');Query OK, 1 row affected, 1 warning (0.03 sec)mysql> show warnings;
+---------+------+----------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------+
| Warning | 1364 | Field 'address' doesn't have a default value |
+---------+------+----------------------------------------------+
1 row in set (0.00 sec)mysql> select * from tb_test;
+----+------------------+----------+---------+
| id | code | username | address |
+----+------------------+----------+---------+
| 1 | sdfdsfdsfdssdfsd | XXXXxxxx | |
+----+------------------+----------+---------+
1 row in set (0.00 sec)mysql>
mysql> show create table tb_test;
+---------+--------------------------------------
| Table | Create Table
+---------+--------------------------------------
| tb_test | CREATE TABLE `tb_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(20) NOT NULL,
`username` varchar(20) NOT NULL,
`address` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------+--------------------------------------
1 row in set (0.01 sec)mysql> select count(*) from tb_test;
+----------+
| count(*) |
+----------+
| 10002 |
+----------+
1 row in set (0.00 sec)mysql> delete from tb_test;
Query OK, 10002 rows affected (0.27 sec)mysql> select count(*) from tb_test;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)mysql>
执行代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start Connection ... "+DateTime.Now.ToString()); string sMySQLConnStr = "Database='csdn';Data Source='localhost';User Id='root'";
MySqlConnection mysqlCnn = new MySqlConnection(sMySQLConnStr);
mysqlCnn.Open(); MySqlCommand mysqlCmd = new MySqlCommand("insert into tb_test(code,username) Values('sdfdsfdsfdssdfsd','XXXXxxxx')", mysqlCnn); Console.WriteLine("Start Insert .... "+DateTime.Now);
for(int i=0;i<5000;i++)
mysqlCmd.ExecuteNonQuery();
Console.WriteLine("Insert accomplished "+DateTime.Now); Console.ReadKey();
}
}
}执行结果Start Connection ... 6/17/2011 2:39:18 PM
Start Insert .... 6/17/2011 2:39:18 PM
Insert accomplished 6/17/2011 2:39:29 PMStart Connection ... 6/17/2011 2:42:56 PM
Start Insert .... 6/17/2011 2:42:56 PM
Insert accomplished 6/17/2011 2:43:06 PM
回复:ACMAIN_CHM C#语言我没有试过,但是如果没有说错的话,C#用的是.net技术吧,我也用过一些LinqTOSQL 但是问题是现在是C++/C反问远程数据的数据库出了问题,并不是C#语言访问远程数据库出了效率低下的问题,同样感谢大牛们的回帖。。期待更多的回复。。问题依旧处在未解决之中。。
没有用你的C测试,直接使用了 C# + MySQL .NET connector. 并没有你所说的情况。你这个代码测试的是不是远程数据库的时间,不要随便拿个本地数据库来测试。远程数据库,我也按照你的代码测试了。。慢得不像样!!!!
我想你这个测试肯定是本地的一个Mysql数据库的,由于建表的时候数据库存储引擎是 INNODB的,我不知道你的数据库引擎采用什么类型的,但是如果的数据库引擎也是INNODB的话,你所写的代码执行效率也是很低的,因为你缺少了事务,(这个我已经测试过了,没有事务,操作本地数据库跟远程差不多,如果有了事务,那么时间大概就是1-2秒)有事务的代码如下(C#)
// string sMySQLConnStr = "Database='db_Test';Data Source='MyServer';User Id='root';Password='xxxx'";
MySqlConnection mysqlCnn = new MySqlConnection(sMySQLConnStr);
mysqlCnn.Open();
MySqlTransaction Tran = mysqlCnn.BeginTransaction();
MySqlCommand mysqlCmd = new MySqlCommand("insert into tba_test(code,username,address) Values('sdfdsfdsfdssdfsd','张三的李','撒开绿灯飞机撒旦立刻解放')", mysqlCnn);
mysqlCmd.Transaction = Tran;
for (int i = 0; i < 5000; i++)
mysqlCmd.ExecuteNonQuery();
mysqlCmd.Transaction.Commit();
MessageBox.Show("SUCCESS");
很感谢你的回答,个人觉得你这个回答本身有小问题,首先,我可以确定,你测试的不是远程的MySQL数据库(或许你所用的MySQL Server 缺省的数据库引擎不一样,而你写出来的代码就是有相当好的效率,但是,在我这边测试,结果却不是这样的)再次感谢、、、