和上一章一样,我们还是插入100条数据,但这次,要求提高数据库的执行效率 ,该怎么做呢?
影响insert执行时间的因素有以下几点:
词法和语义分析
优化Sql语句
执行返回结果
我们做优化很多时候都会去优化 ,例如insert语句,每一次查询都需要分析查询语句,但在一张表中,inset语句几乎相同,只是修改了一些数据,所以我们可以先写一个模板发送给数据库 然后每次插入语句 仅仅修改模板中的几个数据,下次查询,服务器不需要再次分析语句,直接使用模板,更换几个数据即可
这种方法,我们叫做预查(预处理)
第一步,准备模板
prepare str1 from "insert into shop (name,price) values (?,?)";
用问号表示变量
第二步,设置变量
set @a = '小米8';
set @b=2399;
第三步,使用变量插入数据
execute str1 using @a,@b;
和原生类似,MySQLi预处理也分为这几步
1.准备模板,用问号表示变量 —— prepare()
$sql = "insert into user (name,age) VALUES (?,?);";
$pre_sql = $mysql->prepare($sql);
2.设置变量
$name = "lisi";
$age = 20;
3.传入变量
$pre_sql->bind_param('si',$name,$age);
这里要说明一下,bind_param 不仅仅必须传入 变量 也需要对变量类型进行约束,也就是上面代码第一个参数 ‘si’,表示字符串(String)和整型(Integer),如果写成 'ii' ,那么数据库中的name就会变为0
4.插入数据
if (!$pre_sql->execute()){
die('插入失败');
}
为了测试一下两种方法的效率,我们分别用两种方法来添加10000条数据,比较一下时间,代码如下
即时查询
$mysql = new mysqli('localhost', 'root', 'root', 'lianxi', 3306);
$mysql->set_charset('utf8');
$sql = "insert into user(name,age) values ('小明',19)";
$start = microtime(true);
for ($i=0; $i < 10000; $i++) {
$mysql->query($sql);
}
$end = microtime(true);
echo $end-$start;
$mysql->close();
/**
*以下为三次测试结果
*第一次:0.48164105415344
*第二次:0.46934700012207
*第三次:0.47869420051575
*/
预处理查询
$mysql = new mysqli('localhost', 'root', 'root', 'lianxi', 3306);
$mysql->set_charset('utf8');
$sql = "insert into user(name,age) values (?,?)";
$pre_sql = $mysql->prepare($sql);
$name = "小明";
$age = 19;
$start = microtime(true);
for ($i=0; $i <10000 ; $i++) {
$pre_sql->bind_param('si', $name, $age);
$pre_sql->execute();
}
$end = microtime(true);
echo $end-$start;
$mysql->close();
/**
*以下为三次测试结果
*第一次:0.40349793434143
*第二次:0.41533517837524
*第三次:0.41143202781677
*/
可以看到,预查询平均要比即时查询快0.06秒左右,由于插入量小且简单,差距并不是很明显,当我们查询,或者添加更多数据的时候,就可以很明显的看出两者的效率差了。