有一个场景,用户提交一个卡片的核销接口(也可能一次提交多张卡片),如果核销成功则给用户账户加余额。
假如说用户一次提交1000张卡,卡片面值是1元,那每次核销成功我会给用户账号+1元,
我的Order.php
模型中指定了public $connection='mysql'
,而User.php
模型中没有指定这个选项,那默认就是database.php
的default
。然后我发现,这样会出现DB切换的操作,即使默认的default
就是mysql
config/database.php
如下
return [
'default' => 'mysql',
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => get_env('DB_HOST'),
'port' => get_env('DB_PORT'),
'database' => get_env('DB_DATABASE'),
'username' => get_env('DB_USERNAME'),
'password' => get_env('DB_PASSWORD'),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'prefix' => 'wa_',
'strict' => true,
'engine' => null,
],
],
];
模拟代码如下
Db::beginTransaction();
try {
for ($i = 1; $i <= 1000; $i++) {
$data = [
'user_id' => 1, 'order_id' => generateOrderId(), 'created_at' => date('Y-m-d H:i:s'),
];
$orderId = Order::insertGetId($data);
dump($orderId);
User::where('id', 15)->increment('balance', 1);
}
Db::commit();
} catch (\Exception $e) {
dump('rollback', $e->getMessage());
Db::rollback();
}
[SQL] [connection:default] update `wa_users` set `balance` = `balance` + 1, `wa_users`.`updated_at` = '2024-10-17 10:06:07' where `id` = 15 [0.8 ms]
[SQL] [connection:mysql] insert into `wa_order` (`user_id`, `order_id`, `created_at`) values (1, 'WXA2410171006072755222', '2024-10-17 10:06:07') [7.58 ms]
然后我试着把Order.php
模型中的public $connection='mysql'
这个删了,重新跑了一次,日志如下
[SQL] [connection:default] insert into `wa_order` (`user_id`, `order_id`, `created_at`) values (1, 'WXA2410170959592845345', '2024-10-17 09:59:59') [0.49 ms]
[SQL] [connection:default] update `wa_users` set `balance` = `balance` + 1, `wa_users`.`updated_at` = '2024-10-17 09:59:59' where `id` = 15 [0.46 ms]
可以看到,2次执行的sql时间不一样。这次connection都是default,速度就很快。
刚开始以为如果项目只有一个mysql库,然后配置文件中默认的default
值就是指定了登录mysql
,会是等价的。然后今天突发奇想测试了一下,发现是会有点类似上下文切换的操作了。
猜测第一次切换数据库的时候会有一个连接数据库,发送密码,验证密码的过程,耗时多应该是这个过程导致的。
等验证完毕后切换应该就一样快了。
php-fpm传统框架为什么这么慢,重复连接数据库验证密码最后又断开数据库,这些很耗时,而且对Mysql服务器消耗也大。
webman没这些消耗,所以快很多很多。
我贴了2行日志,其实后面1000条日志都是这样。default的那个connection每次都是0.几毫米,connnection=mysql的每次都是7.几毫秒。 我现在也纳闷呢
webman嘛?还是tp lv?
webman