限制where子句中的结果集会提高group by和having的性能吗?

Will limiting the result set in the where clause improve the performance of group by and having?

我有一个 MySQL table 超过 2500 万行。因此,为了防止关闭整个数据库,我不想执行任何会导致在磁盘上创建临时 tables 的查询,例如在未索引的列上排序。

所以如果 table 有以下列…

 employee_id
 first_name
 last_name
 hire_date
 manager_id

假设我想看到那些有 3 名或更多员工为他们工作的经理(假设 manager_id 没有索引)..

select count(*), manager_id from employee group by manager_id  having count(id) > 3

如果我将结果集限制为仅 2016 年之后雇用的员工,它是否有助于此查询的性能....

select count(*), manager_id from employee where hire_date > ‘2016-01-01’ 
group by manager_id having count(id) > 3

让我们假设 hire_date 也没有索引。那个额外的 where 子句会有帮助吗?

我认为如果数据量由于 where 子句而显着减少,那肯定会有帮助。

虽然除了自己尝试之外别无选择。

是的,限制 WHERE 子句中的行意味着要分组的行会更少,有些组甚至不会显示,因为该组中的行已被过滤掉.

GROUP BY 可能会在您的查询中创建一个临时的 table。但至少它会是一个较小的温度 table 因为会有更少的组。避免 temp table 的方法是通过 manager_id.

上的索引按索引顺序进行查询扫描

MySQL 如果可以保证按 manager_id 顺序扫描,就可以避免 temp table,因此可以更轻松地计算每个组中的行数,假设它连续扫描每个组。换句话说,当它到达给定 manager_id 的最后一行时,它知道不能再有相同 manager_id 的行。因此它不需要记录每个 manager_id 的计数。当它完成扫描每组行时,它可以只输出每个 manager_id 的计数。

但是您可能会发现 hire_date 上的索引有更大的好处。如果该条件可以通过从 hire_date > '2016-01-01' 所在的行开始来避免扫描大部分 table,那么临时 table 的成本可能小于 table- 的成本扫描.

无法进行既按 manager_id 上的索引扫描又按 hire_date 上的索引扫描的查询。哪种策略更好取决于您 table 匹配不同条件的行数。

愚蠢。

我可以向您展示一个 10 行 table 和一个查询(有 JOIN,但没有 GROUP BY),它们将消耗 1 TB 的临时 space磁盘。

我的观点是,没有简单的方法可以防止来自 "crashing the system" 的恶意查询。

在您的 "hire-date" 修复中,如果经理在 2016 年之前有 2 名员工,2016 年之后有 2 名员工怎么办?您的 "improved" 查询将无法找到他们的经理。

拥有 INDEX(manager_id) 会造成 一些 差异,但仍然会有 "full index scan",仅比 "full table scan" 略好一些。

添加 hire_date 子句不一定有帮助。特别是,INDEX(hire_date) 根本 不太可能有帮助。即使 INDEX(hire_date, manager_id) (但不是其他顺序)也会帮助 some.

这只是对该相对简单查询的部分分析。其他查询的范围呢?愚蠢。

有一件事会有所帮助:使用 InnoDB,而不是 MyISAM。