下面是ecshop 的商品表和品牌表的查詢,請問它們的查詢效率有什么區別呢?
還有一個問題是 left join 和join的效率哪個高一點呢。
謝謝 !!
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS aLEFT JOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE a.`brand_id` = b.`brand_id`
回復討論(解決方案)
你的第一式是左鏈接,因無其他過濾條件
結果集中將會有左表(ecs_goods)的全部記錄
你的第二式是逗號連接(INNER JOIN 的簡寫)
結果集中只會出現符合連接條件的記錄
兩者的作用是不同的,不能做效率比較
當右表(ecs_brand)有過濾條件時
左連接退化為內連接,兩式就一樣了,沒有差別
你的第一式是左鏈接,因無其他過濾條件
結果集中將會有左表(ecs_goods)的全部記錄
你的第二式是逗號連接(INNER JOIN 的簡寫)
結果集中只會出現符合連接條件的記錄
兩者的作用是不同的,不能做效率比較
版主 那是不是第一個sql刪去left,就和第二個sql完全一樣的呢。
它們在效率和索引使用方面有沒區別的呢。
當右表(ecs_brand)有過濾條件時
左連接退化為內連接,兩式就一樣了,沒有差別
版主 謝謝你的回答。我還有個問題
比如商品必須選擇品牌,就是商品必定存在品牌id。
然后是品牌表肯定有商品的品牌。
所以它們用left join,或是join 返回的結果是一樣的。 那這樣它們可以進行效率對比嗎。
由于連接外有過濾條件,所以 mysql 會將你的查詢指令優化成內連接。因此就不存在效率的對比了
當然這里可以對比的是:
在商品表中查品牌商品 和 在品牌表中查商品
兩者的效率是不一樣的
因為品牌表顯然要比商品表小
由于連接外有過濾條件,所以 mysql 會將你的查詢指令優化成內連接。因此就不存在效率的對比了
當然這里可以對比的是:
在商品表中查品牌商品 和 在品牌表中查商品
兩者的效率是不一樣的
因為品牌表顯然要比商品表小
版主 謝謝你的回答
我總結了一下你的回答:
第一點:SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE a.`brand_id` = b.`brand_id`
和
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS aJOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
兩句sql是完全一樣的 mysql會將第一條sql優化成第二條。
第二點:
“在商品表中查品牌商品 和 在品牌表中查商品”
就是說
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS aJOIN ecs_brand AS b ON a.`brand_id` = b.`brand_id`
和
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM ecs_brand AS bJOIN `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次。 那為什么它們的效率不一樣呢
呵呵,你自己偷換概念,給自己上個套!完全是為了你的錯誤觀點SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE a.`brand_id` = b.`brand_id`和
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `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_nameFROM `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_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE a.`brand_id` = b.`brand_id`AND b.`field_name`= 123
呵呵,你自己偷換概念,給自己上個套!完全是為了你的錯誤觀點SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE a.`brand_id` = b.`brand_id`和
SELECT a.`goods_id` , a.`goods_name` , b.brand_nameFROM `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_nameFROM `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_nameFROM `ecs_goods` AS a, ecs_brand AS bWHERE 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, '三星');
版主 請問這些mysql的資料在哪里可以找到的呢,比如怎樣知道某些語句在mysql里面會優化成另外的語句呢。