db::connection连接问题

lepig

问题说明

有一个场景,用户提交一个卡片的核销接口(也可能一次提交多张卡片),如果核销成功则给用户账户加余额。

假如说用户一次提交1000张卡,卡片面值是1元,那每次核销成功我会给用户账号+1元,

我的Order.php模型中指定了public $connection='mysql',而User.php模型中没有指定这个选项,那默认就是database.phpdefault。然后我发现,这样会出现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日志如下

[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,会是等价的。然后今天突发奇想测试了一下,发现是会有点类似上下文切换的操作了。

283 1 0
1个评论

damao

猜测第一次切换数据库的时候会有一个连接数据库,发送密码,验证密码的过程,耗时多应该是这个过程导致的。
等验证完毕后切换应该就一样快了。
php-fpm传统框架为什么这么慢,重复连接数据库验证密码最后又断开数据库,这些很耗时,而且对Mysql服务器消耗也大。
webman没这些消耗,所以快很多很多。

  • lepig 2024-10-17

    我贴了2行日志,其实后面1000条日志都是这样。default的那个connection每次都是0.几毫米,connnection=mysql的每次都是7.几毫秒。 我现在也纳闷呢

  • tanhongbin 2024-10-22

    webman嘛?还是tp lv?

  • lepig 2024-10-22

    webman

lepig

210
积分
0
获赞数
0
粉丝数
2024-10-01 加入
×
🔝