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

时间:2018-07-09 17:27:28

标签: mysql query-performance

我有一个超过2500万行的MySQL表。因此,为了避免破坏整个数据库,我不想进行任何查询,这些查询会导致在磁盘上创建临时表,例如对未索引列的排序。

因此,如果表具有以下列...

 employee_id
 first_name
 last_name
 hire_date
 manager_id

假设我想看到有3名或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子句会有所帮助吗?

3 个答案:

答案 0 :(得分:2)

是的,限制WHERE子句中的行意味着要分组的行将更少,并且某些组甚至不会显示,因为该组中的行已经被过滤掉了。 / p>

GROUP BY可能会在您的查询中创建一个临时表。但是至少它将有一个较小的临时表,因为将有较少的组。避免使用临时表的方法是按manager_id上的索引以索引顺序进行查询扫描。

如果MySQL可以确定可以按manager_id进行扫描,则可以避免使用temp表,因此假定连续扫描每个组,它可以更轻松地计算每个组中的行。换句话说,当它到达给定manager_id的最后一行时,它知道该相同的manager_id不会再有更多行了。因此,不需要对每个manager_id的计数进行计数。完成扫描每组行后,它只能输出每个manager_id的每个计数。

但是您可能会发现hire_date上的索引具有更大的优势。如果这种情况可以通过从hire_date > '2016-01-01'的行开始避免扫描大部分表,那么临时表的开销可能小于表扫描的开销。

无法进行通过manager_id上的索引扫描和也通过hire_date上的索引扫描的查询。哪种策略更好,取决于表中有多少行匹配不同的条件。

答案 1 :(得分:0)

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

尽管没有其他选择可以自己尝试。

答案 2 :(得分:0)

愚蠢。

我可以为您显示10行表和一个查询(使用JOIN,但不使用GROUP BY),这将占用磁盘上的TB临时空间。

我的意思是,没有简单的方法可以防止流氓查询“使系统崩溃”。

在您的“雇用日期”修复程序中,如果经理在2016年之前有2名员工,而在之后有2名员工,该怎么办?您的“改进”查询将找不到他们的经理。

具有INDEX(manager_id)会使有些有所不同,但仍然会有“全索引扫描”,仅比“全表扫描”好一点。

添加hire_date子句不一定有帮助。特别地,INDEX(hire_date)不可能完全帮助 。甚至INDEX(hire_date, manager_id)(但不是其他顺序)也可以帮助一些

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

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