验证数据是否存在

        DB::enableQueryLog();
        if (User::where('role_id', 1)->first()) {
            dump('存在');
        }

        if (User::where('role_id', 1)->exists()) {
            dump('存在');
        }
        dd(DB::getQueryLog());

SQL

array:2 [
  0 => array:3 [
    "query" => "select * from `users` where `role_id` = ? limit 1"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 20.23
  ]
  1 => array:3 [
    "query" => "select exists(select * from `users` where `role_id` = ?) as `exists`"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 19.58
  ]
]

发现第二种查询明显快过第一种。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 6

可以试下数据不存在时,还有role_id 是多个结果的数据时,

5年前 评论
半人间 (楼主) 5年前

有测试过数据量大的时候是什么情况吗

5年前 评论
半人间 (楼主) 5年前

模拟了 64万数据的表 而 username并没有索引

array:2 [
0 => array:3 [
"query" => "select id from user where username = ? limit 1"
"bindings" => array:1 [
0 => "zhangsan"
]
"time" => 271.23
]
1 => array:3 [
"query" => "select exists(select * from user where username = ?) as exists"
"bindings" => array:1 [
0 => "zhangsan"
]
"time" => 54.71
]
]

5年前 评论

毫无争议的第二种,使用exists是最好的选择。

在业务中只是判断数据是否存在,第一种在逻辑上似乎不是很好,因为这只是判断是否存在,而不需要获取全部数据。其次查询中使用select 是不好的习惯*,除非需求是真的需要这一行的所有数据。

使用exists为什么是最好的选择,因为exists从语义上来说就表达很明确了,然后它返回的是一个布尔值,响应速度更加快。最后exists是优化了子语句中的select 这个不好的习惯*的,mysql是直接忽略select表。

5年前 评论
颠倒的玉石

看业务吧,如果真的是单纯只是判断存不存在,肯定还是专项专用比较好,不然这个exists函数存在意义很小了

5年前 评论

file,这是通过 explain 进行分析的,你的role_id 是关联表的主键, 我这也是关联表的主键; 你可以自行尝试,这 孙子开挂,怎么和他比 :sweat:

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!