我想知道对于一个简单的事情,性能和编程风格有什么好处:从一个表中获取2个值的计数(以下所有查询都执行相同的工作)。
进行2次单一查询:
SELECT count(*) FROM `a` WHERE categories_id=2
SELECT count(*) FROM `a` WHERE group_id=92
或使用子查询
SELECT (SELECT count(*) FROM `a` WHERE categories_id=2 AS categories)
,(SELECT count(*) FROM `a` WHERE group_id=92) AS groups)
或联盟
SELECT count(*) FROM `a` WHERE categories_id=2
UNION
SELECT count(*) FROM `a` WHERE group_id=92
答案 0 :(得分:1)
三者之间的主要区别在于处理结果值,尽管这不是创伤。
性能方面,只有两行数据,三者之间几乎没有选择。第二个(两个子查询)解决方案使用单个语句执行最多,并且只需要一次提取操作,因此它可能是最快的。第一个需要单独解析两个语句,再加上两组操作,所以它应该是最慢的。但是,你能否真正衡量这取决于很多因素。如果客户端位于澳大利亚且服务器位于欧洲,则往返延迟可能意味着第二个或第三个解决方案最佳(差异可能取决于DBMS是否使用单个客户端 - 服务器返回多个行消息交换)。如果客户端与服务器位于同一台计算机上,那么往返延迟就不那么重要了。
为了便于理解,UNION版本可能足够干净;它不会混淆任何读它的人。第一个版本可能稍微清晰一点(少一个关键字)但差别很小。
如果替代品的数量增加(超过一个group_id
值,或多于一个categories_value
),那么我认为UNION在清晰度上获胜:
SELECT 'G' AS type, group_id, COUNT(*)
FROM a
WHERE group_id IN (92, 104, 137, 291)
GROUP BY type, group_id
UNION
SELECT 'C' AS type, categories_id, COUNT(*)
FROM a
WHERE categories_id IN (2, 3, 13, 17, 19, 21)
GROUP BY type, categories_id
'type'列允许您区分组ID和共享相同ID号的类别ID(尽管它们是两种不同类型的ID)。
因为它更容易扩展,所以我可能选择3(UNION),除非在实时数据上有令人信服的计时实验,以表明选项2(子查询)实际上更快。
答案 1 :(得分:0)
第一个选项,执行两个SELECT,总是效率稍低,因为它涉及到数据库的额外往返。在第二个之间,因为UNION将导致数据库必须对值进行排序并建立联合,因此联合版本在理论上会稍微慢一些。实际上,对于只有两个值,这对于查询的两个主要部分的时间是不可测量的。