mysql求助 请问where a.id=b.id 和join on a.id=b.id 在效率上的区别

anydy2008 2013-12-01 04:49:51
下面是ecshop 的商品表和品牌表的查询,请问它们的查询效率有什么区别呢?
还有一个问题是 left join 和join的效率哪个高一点呢。
谢谢 !!

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a
LEFT JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`


SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`


...全文
702 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2013-12-02
  • 打赏
  • 举报
回复
呵呵,你自己偷换概念,给自己上个套!完全是为了你的错误观点
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a INNER JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
是等效的
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a LEFT JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
WHERE b.`field_name`= 123
会被 mysql 优化为
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`AND b.`field_name`= 123
anydy2008 2013-12-02
  • 打赏
  • 举报
回复
引用 5 楼 xuzuning 的回复:
由于连接外有过滤条件,所以 mysql 会将你的查询指令优化成内连接。因此就不存在效率的对比了 当然这里可以对比的是: 在商品表中查品牌商品 和 在品牌表中查商品 两者的效率是不一样的 因为品牌表显然要比商品表小
版主 谢谢你的回答 我总结了一下你的回答: 第一点:

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a
JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id` 
两句sql是完全一样的 mysql会将第一条sql优化成第二条。 第二点: “在商品表中查品牌商品 和 在品牌表中查商品” 就是说

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  `ecs_goods` AS a
JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id` 

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM  ecs_brand AS b
JOIN `ecs_goods` AS a ON b.`brand_id`=a.`brand_id` 
两句sql的效率是不一样的。 ////////////////////////////////////////////////////////////// 以上两点描述正确吗 ?我有没理解错你的意思呢。 如果没有 那第二点大家处理方式都是笛卡尔积。 我的理解是 如果是 ecs_goods` AS a JOIN ecs_brand AS b 那就是商品表的一条记录 扫描品牌表的所有记录。如果有10个商品 10个品牌 那就是10*10=100 扫描了100次 反过来ecs_brand AS b JOIN `ecs_goods` AS a 一个品牌扫描10个商品 那扫描次数也是100次。 那为什么它们的效率不一样呢
anydy2008 2013-12-02
  • 打赏
  • 举报
回复
版主 请问这些mysql的资料在哪里可以找到的呢,比如怎样知道某些语句在mysql里面会优化成另外的语句呢。
anydy2008 2013-12-02
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
呵呵,你自己偷换概念,给自己上个套!完全是为了你的错误观点
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`

SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a INNER JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`

是等效的
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a LEFT JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
WHERE b.`field_name`= 123

会被 mysql 优化为
SELECT a.`goods_id` , a.`goods_name` , b.brand_name
FROM `ecs_goods` AS a, ecs_brand AS b
WHERE a.`brand_id` = b.`brand_id`AND b.`field_name`= 123



版主 这两条语句我试了一下,好像是不相等的阿。

--
-- 表的结构 `good_tbl`
--

CREATE TABLE `good_tbl` (
`good_id` int(10) unsigned NOT NULL auto_increment,
`brand_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`good_id`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk AUTO_INCREMENT=4 ;

--
-- 导出表中的数据 `good_tbl`
--

INSERT INTO `good_tbl` VALUES (1, 2);
INSERT INTO `good_tbl` VALUES (2, 3);
INSERT INTO `good_tbl` VALUES (3, 2);




--
-- 表的结构 `brand_tbl`
--

CREATE TABLE `brand_tbl` (
`brand_id` int(10) unsigned NOT NULL auto_increment,
`brand_name` varchar(50) NOT NULL,
PRIMARY KEY (`brand_id`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk AUTO_INCREMENT=4 ;

--
-- 导出表中的数据 `brand_tbl`
--

INSERT INTO `brand_tbl` VALUES (1, '诺基亚');
INSERT INTO `brand_tbl` VALUES (3, '三星');




xuzuning 2013-12-01
  • 打赏
  • 举报
回复
由于连接外有过滤条件,所以 mysql 会将你的查询指令优化成内连接。因此就不存在效率的对比了 当然这里可以对比的是: 在商品表中查品牌商品 和 在品牌表中查商品 两者的效率是不一样的 因为品牌表显然要比商品表小
anydy2008 2013-12-01
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
当右表(ecs_brand)有过滤条件时 左连接退化为内连接,两式就一样了,没有差别
版主 谢谢你的回答。我还有个问题 比如商品必须选择品牌,就是商品必定存在品牌id。 然后是品牌表肯定有商品的品牌。 所以它们用left join,或是join 返回的结果是一样的。 那这样它们可以进行效率对比吗。
anydy2008 2013-12-01
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
你的第一式是左链接,因无其他过滤条件 结果集中将会有左表(ecs_goods)的全部记录 你的第二式是逗号连接(INNER JOIN 的简写) 结果集中只会出现符合连接条件的记录 两者的作用是不同的,不能做效率比较
版主 那是不是第一个sql删去left,就和第二个sql完全一样的呢。 它们在效率和索引使用方面有没区别的呢。
xuzuning 2013-12-01
  • 打赏
  • 举报
回复
当右表(ecs_brand)有过滤条件时 左连接退化为内连接,两式就一样了,没有差别
xuzuning 2013-12-01
  • 打赏
  • 举报
回复
你的第一式是左链接,因无其他过滤条件
结果集中将会有左表(ecs_goods)的全部记录

你的第二式是逗号连接(INNER JOIN 的简写)
结果集中只会出现符合连接条件的记录

两者的作用是不同的,不能做效率比较

21,882

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧