前言:最近用到了远程连接MySql数据库,多表联合查询,其中两张表有小量数据(100)条左右下文中暂称为A、B表,其中一张表C有几万条数据,并且实时在更新中。。。持续增长。。。。
经验:一次简单的多表联合查询中可以看出,减少循环,循环中语句尽量简单,减少内存占用,书写SQL要合理
一、简单需求描述:通过输入的字段查询获取到A表中的与B表中共同的某ID列,通过该ID列获取B表中某表名列和属性列,同时B中的属性列和C表中某字段列相同;A和B中ID列一一对应,但一个ID属性对应多个B表中表名列和属性列,同时B表和C表相同字段列为一一对应关系;即一个A对应多个B==多个C
目的:通过输入的A条件查询到B中的表名列和C表中数据列;表示意如下:
二、实现过程:
1、第一次解决思路:先根据输入的A的eqname查找到EQUSID,通过联合查询得到B的SR_table值,A.equsid =B.equsid; 因为一对多,所以得到的是多个SR_table,将得到B的值集合循环遍历,同时在遍历中写入sql,通过SR_table查询SR_name再B.sr_name= C.MeterCode 查询到C中的EnvDataH,将SR_table,EnvDataH以键值对形式存放起来,后续使用。
源码如下:
using mysql.data.sqlclient;
string selectTxt="";
Dictionary<string, string> DI = new Dictionary<string, string>();
string sql = "SELECT A.EQUSID,B.SR_table FROM A left JOIN B ON A.EQUSID = B.EQUSID WHERE A.eqname = '" + this.txtSelect.Text + "'";
string connetStr = "server=123.56.1.1;port=3306;user=root;password=123; database=base;CharSet=gb2312;";
server=127.0.0.1/localhost 代表本机,端口号port默认是3306可以不写
try
{
MySqlConnection conn = new MySqlConnection(connetStr);
conn.Open();
MySqlCommand cmd = new MySqlCommand(sql, conn);
//cmd.CommandType = CommandType.Text;
DataTable dt = new DataTable();
MySqlDataAdapter adpter = new MySqlDataAdapter(cmd);
adpter.Fill(dt);
conn.Close();
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
this.txtSend.AppendText(dt.Rows[i][1].ToString()+"\r\n");//没用的
selectTxt = dt.Rows[i][1].ToString();
MySqlConnection conn1 = new MySqlConnection(connetStr);
conn1.Open();
string sql2 = "SELECT V.EnvDataH FROM B LEFT JOIN B ON B.SR_name = C.MeterCode WHERE B.SR_table = '" + selectTxt + "' ORDER BY C.ReadingDt DESC LIMIT 1, 1";
MySqlCommand cmd1 = new MySqlCommand(sql2, conn1);
cmd1.CommandType = CommandType.Text;
DataTable dt1 = new DataTable();
MySqlDataAdapter adpter1 = new MySqlDataAdapter(cmd1);
adpter1.Fill(dt1);
conn1.Close();
if (dt1.Rows.Count > 0)
{
this.txtSend.AppendText(dt1.Rows[0][0].ToString() + "\r\n");//没用的
this.txtSend.AppendText(adpter1 + "2222\r\n");//没用的
}
else
{
this.txtSend.AppendText("空\r\n");//没用的
}
}
}
//在这里使用代码对数据库进行增删查改
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// conn.Close();
}
2.代码书写完毕,运行也没有问题但是。。。。就是查询10秒左右,挺慢,然后一直思考是哪的问题,最后认为是循环中查询语句,打开关闭数据库太繁琐,没有合理利用,在循环中联合查询太占用内存,然后稍微修改了一下,就是在第一次查询中通过A中的ID连接到B中,查询到SR_table后同时查询出SR_name,并在循环中不再遍历SR_table,而是遍历C表中也存在的SR_name,循环中也只是查询单表C,将数据取出。这样修改之后,速度果然快了几倍。
代码:
string sql = "SELECT B.SR_table, B.SR_name FROM A left JOIN B ON A.EQUSID = B.EQUSID WHERE A.eqname = '" + this.txtSelect.Text + "'";
string sql2 = "SELECT C.EnvDataH FROM C WHERE C.MeterCode = '" + selectTxt + "' ORDER BY C.ReadingDt DESC LIMIT 1, 1";