0

在这篇文章中:SQL Query to get the data

第一个答案是:

SELECT students.student_id,student_name,father_name,mother_name,
           COUNT(student_addresses.student_id) AS total_addresses,    
           COUNT(student_phones.student_id) AS total_phones
     FROM students,student_phones,student_addresses
     WHERE students.student_id = student_phones.student_id AND
           students.student_id = student_addresses.student_id AND
           students.student_id = 7
    GROUP BY BY students.student_id,student_name,father_name,mother_name;

而第二个是:

SELECT s.student_id,
       max(s.student_name) student_name,
       max(s.father_name) father_name,
       max(s.mother_name) mother_name,
       COUNT(distinct a.student_address_id) total_addresses,    
       COUNT(distinct p.student_phone_id) total_phones
FROM students s
LEFT JOIN student_phones p ON s.student_id = p.student_id
LEFT JOIN student_addresses a ON s.student_id = a.student_id
WHERE s.student_id = 7
GROUP BY s.student_id

现在,问题是:在性能方面,这两个查询之间是否存在显着差异?使用 是否MAX()会影响第二个查询的执行时间?

我尝试用谷歌搜索答案,但没有运气。我想要一个清晰而具体的解释。

4

1 回答 1

1

即使四列都是唯一的(students.student_id, student_name, father_name, mother_name),这两个查询也不会做同样的事情。

从逻辑的角度来看,这两个查询并不相同。对于没有电话或地址的学生,第一个将不返回任何行。第二个将返回这样的学生。此外,计数值不同(取决于数据)。

从性能的角度来看,主要区别在于:

       COUNT(student_addresses.student_id) AS total_addresses,    
       COUNT(student_phones.student_id) AS total_phones

相对:

       COUNT(distinct student_addresses.student_id) AS total_addresses,    
       COUNT(distinct student_phones.student_id) AS total_phones

使用count(distinct)成本更高,因为 SQL 引擎必须维护所有值的列表。在极端情况下,这些值可能会超出内存,甚至会导致更多的 I/O 操作。对于 a count(),引擎只是将一个数字加一,而不是进行繁琐的列表操作。

min()同样, and的开销max()也是最小的——引擎进行比较并覆盖一个值。这是一小部分额外工作,不太可能影响性能。平衡这一点的事实是group by密钥更短。较短的密钥可能会对性能产生影响,具体取决于所使用的底层算法。无论如何,这两个查询都有相同数量的数据被 处理group by,因此密钥长度(无论算法如何)的总体差异可能很小。

简而言之,性能上的任何差异都是由于.count(distinct)而不是max(). 您应该决定这是否是您真正需要的,并据此编写查询。第二种形式更好,因为它使用 ANSI 标准连接语法。

于 2013-07-23T11:02:53.140 回答