我有两张桌子:
CREATE TABLE `bb_index` (
`bb_id` smallint(5) unsigned NOT NULL,
`object_id` bigint(10) unsigned NOT NULL,
`in_object_id` bigint(10) unsigned NOT NULL,
`f` int(10) unsigned DEFAULT NULL,
`length` decimal(10,5) DEFAULT NULL,
PRIMARY KEY (`bb_id`,`object_id`,`in_object_id`),
KEY `in_obj_key` (`bb_id`,`in_object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `obj_bb_relation` (`bb_id` smallint(5) unsigned NOT NULL DEFAULT '0',
`object_id` bigint(10) unsigned NOT NULL DEFAULT '0',
`object_bb_f` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`bb_id`,`object_id`),
KEY `object_id` (`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
哪个更好: 选项1:
SELECT object_id, f, length , object_bb_freq as C
FROM (select object_id, f, length
from bb_index use index (in_obj_key)
where bb_id = 14
and in_object_id = XXX
) as a join obj_bb_relation as b using (object_id)
说明:
选项2:
SELECT object_id, f, length, object_bb_f AS C
FROM bb_index AS a
JOIN obj_bb_relation AS b USING ( object_id )
WHERE in_object_id = XXX
AND a.bb_id =YY
AND b.bb_id =YY
OR?
另一种选择..?
答案 0 :(得分:0)
在大多数情况下两者都是相同的。大多数数据库系统现在都有查询优化,它会自动从查询2,查询1进行查询。甚至更好。但是如果你使用一些非常旧的或简化的数据库,选项1会更好。除了一些非常特殊的情况,加入应该是最后的。
答案 1 :(得分:0)
首先,您的查询几乎不相似!
SELECT object_id, f, length , object_bb_freq as C
FROM (select object_id, f, length
from bb_index use index (in_obj_key)
where bb_id = 14 and in_object_id = XXX) as a
join obj_bb_relation as b
using (object_id)
SELECT object_id, f, length, object_bb_f AS C
FROM bb_index AS a
JOIN obj_bb_relation AS b
USING ( object_id )
WHERE in_object_id = XXX AND a.bb_id =YY AND b.bb_id =YY
翻译中缺少非常重要的位,即
除此之外,因为您使用了ANSI INNER JOIN表单而不是逗号形式(FROM bb_index, obj_bb_relation WHERE ..
),所以MySQL会根据需要随机播放WHERE和ON / USING子句,因为它们是在语义上是一样的。这与你已经subqueried a的事实无关,因为MySQL非常聪明,可以展开它。
就个人而言,由于你在a.bb_id和b.bb_id上都有过滤器,如果你知道一个表只返回另一个表的1%的记录,那么你可以使用经常被诽谤的逗号。表示法(FROM bb_index, obj_bb_relation WHERE ..
)因为MySQL会在加入bb_index
之前处理obj_bb_relation
上的过滤器 - 否则我通常会使用展平的JOIN表单(选项2),因为它比子查询更清晰在选项1)