有一個(gè)場(chǎng)景,用戶提交一個(gè)卡片的核銷接口(也可能一次提交多張卡片),如果核銷成功則給用戶賬戶加余額。
假如說(shuō)用戶一次提交1000張卡,卡片面值是1元,那每次核銷成功我會(huì)給用戶賬號(hào)+1元,
我的Order.php
模型中指定了public $connection='mysql'
,而User.php
模型中沒有指定這個(gè)選項(xiàng),那默認(rèn)就是database.php
的default
。然后我發(fā)現(xiàn),這樣會(huì)出現(xiàn)DB切換的操作,即使默認(rèn)的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'
這個(gè)刪了,重新跑了一次,日志如下
[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次執(zhí)行的sql時(shí)間不一樣。這次connection都是default,速度就很快。
剛開始以為如果項(xiàng)目只有一個(gè)mysql庫(kù),然后配置文件中默認(rèn)的default
值就是指定了登錄mysql
,會(huì)是等價(jià)的。然后今天突發(fā)奇想測(cè)試了一下,發(fā)現(xiàn)是會(huì)有點(diǎn)類似上下文切換的操作了。
猜測(cè)第一次切換數(shù)據(jù)庫(kù)的時(shí)候會(huì)有一個(gè)連接數(shù)據(jù)庫(kù),發(fā)送密碼,驗(yàn)證密碼的過程,耗時(shí)多應(yīng)該是這個(gè)過程導(dǎo)致的。
等驗(yàn)證完畢后切換應(yīng)該就一樣快了。
php-fpm傳統(tǒng)框架為什么這么慢,重復(fù)連接數(shù)據(jù)庫(kù)驗(yàn)證密碼最后又?jǐn)嚅_數(shù)據(jù)庫(kù),這些很耗時(shí),而且對(duì)Mysql服務(wù)器消耗也大。
webman沒這些消耗,所以快很多很多。