mysql/sqlserver中exists与left join效率对比

背景

        探究使用exists或left join判断一条数据在另一个表中是否存在时,谁的效率更高。SQL语句如下:

        select * from table1 where exists(select 1 from table2 where [table1.column]=[table2.column])

        select * from table1 left join table2 on [table1.column]=[table2.column]
        where [table2.column] is not null

对比过程

sqlserver中的效率对比

exists 执行时间:15秒

left join执行时间:27秒

        根据下面两张图中的执行计划的结果来看,很明显,left join 比exists多执行一步,使用exists时,从头到尾扫描完索引进行条件检索,数据结果也就有了,而left join中,从头到尾扫描完索引检索后只是刚拿到left join 的结果,还没拿到最终结果,紧跟着还要执行联合查询,因为两个结果集inner join时没有索引,走的全表扫描,因此慢,比exists的方式多执行了12秒。

mysql中效率对比

exists 执行时间:13秒

left join执行时间:14秒

        看如下两张执行计划图,与sqlserver一样,left join比exists多了一步。在exists中,利用a表的索引与b表的主键匹配迅速找出数据并判断条件是否符合,索引匹配完成,数据结果也就有了。但left join不一样,left join在exists的执行步骤的基础上,还做了一步inner join,本文例子中,mysql的left join只比exists多执行了1秒,是因为有索引,联合查询时利用了索引,上面的sqlserver在inner join时是没有索引的,因此sqlserver中的差距大,倒不是说sqlserver的效率本身低。

结论

关于使用exists或left join判断一条数据在另一个表中是否存在时,谁的效率更高的验证结论:

        1、无论mysql还是sqlserver都是exists比left join效率高——因为exists一步完成,left join需要2步,而且第一步与exists一致,相当于多了一步。

        2、没有索引的情况下,执行时间将近相差一倍——因为left join的第二步全表扫描耗时

        3、有索引的情况下,差异不算太大——因为left join的第二步利用索引,相对耗时就少。

        4、保持使用exists的习惯吧——毕竟从执行计划看,exists只走一步,left join走两步,而且第一步与exists一致

  • 20
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
创建表的SQL语句可以根据具体需求和字段定义来编写。以MySQL为例,以下是一个示例的创建表的SQL语句: ```sql CREATE TABLE IF NOT EXISTS `users` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `age` INT(3) NOT NULL, `email` VARCHAR(100) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` 上述的SQL语句创建了一个名为`users`的表,包含了四个字段:`id`、`name`、`age`和`email`。其`id`是主键,并且使用自增的方式进行编号。`name`和`email`字段分别是最大长度为50和100的字符串,`age`字段为整数类型。 另外,还可以在创建表的SQL语句添加一些约束,如唯一性约束或外键约束等。以下是一个示例的带有约束的创建表的SQL语句: ```sql CREATE TABLE IF NOT EXISTS `orders` ( `order_id` INT(11) NOT NULL AUTO_INCREMENT, `user_id` INT(11) NOT NULL, `product_id` INT(11) NOT NULL, `quantity` INT(3) NOT NULL, PRIMARY KEY (`order_id`), UNIQUE KEY `unique_order` (`user_id`, `product_id`), FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` 上述的SQL语句创建了一个名为`orders`的表,包含了四个字段:`order_id`、`user_id`、`product_id`和`quantity`。其`order_id`是主键,并且使用自增的方式进行编号。`user_id`和`product_id`字段组合成了一个唯一性约束,即一个用户在购买同一个商品时只能有一个订单。另外,`user_id`和`product_id`字段分别作为外键,分别引用了`users`和`products`表的对应字段。同时,添加了`ON DELETE CASCADE`的外键约束,表示在删除对应表的记录时,该表的相关记录也会被自动删除。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微差

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值