做的网站文字是乱码,外国人讲汉语做网站的视频,重庆建设工程质量协会网站,网页设计与制作模板免费在联接处理中#xff0c;前缀行是从联接查询中的一个表传递到下一个表的那些行。
通常#xff0c;优化器会尝试在联接查询的早期放置前缀计数较低的表#xff0c;以防止行组合的数量快速增加。
在某种程度上#xff0c;优化器可以使用从一个表中选择并传递到下一个表的行…在联接处理中前缀行是从联接查询中的一个表传递到下一个表的那些行。
通常优化器会尝试在联接查询的早期放置前缀计数较低的表以防止行组合的数量快速增加。
在某种程度上优化器可以使用从一个表中选择并传递到下一个表的行的条件信息它就可以越准确地计算行评估并选择最佳执行计划。
在没有条件过滤的情况下表的前缀行计数基于WHERE子句根据优化器选择的任何访问方法选择的估计行数。条件过滤使优化器能够在WHERE子句中使用访问方法未考虑的其他相关条件从而改进其前缀行计数估计。
例如即使可能有一种基于索引的访问方法可以用于在联接中从当前表中选择行WHERE子句中也可能有针对该表的附加条件可以过滤进一步限制传递给下一个表的符合条件的行的估计数。 博主PS阅读了嵌套联接优化博客的朋友应该可以联想到只要控制外层循环的条件满足的次数或概率就能减少内层for循环的次数。上文中的“进一步限制”有类似的作用 【MySQL精通之路】SQL优化(1)-查询优化(7)-嵌套循环联接-CSDN博客 只有在以下情况下条件才有助于滤波估计 1.它指的是当前表。 2.它取决于联接序列中早期表中的一个或多个常数值。 3.访问方法尚未将其考虑在内。 在EXPLAIN输出中rows列表示所选访问方法的行估计而filtered列反映条件筛选的效果。filtered值以百分比表示。最大值为100这意味着没有对行进行筛选。从100开始递减的值表示过滤量的增加。
前缀行计数估计从联接中的当前表传递到下一个表的行数是行和筛选值的乘积。
也就是说前缀行计数是估计的行计数减去估计的过滤效果。例如如果行数为1000过滤为20%则条件过滤会将估计的行数1000减少为前缀行数1000×20%1000×.2200。
请考虑以下查询
SELECT *FROM employee JOIN department ON employee.dept_no department.dept_noWHERE employee.first_name JohnAND employee.hire_date BETWEEN 2018-01-01 AND 2018-06-01;
假设数据集具有以下特征 员工表有1024行。 部门表有12行。 两个表都有dept_no的索引。 employee表在first_name上有一个索引。 employee.first_name上有8行满足此条件 employee.first_name John employee.hire_date上有150行满足此条件 employee.hire_date BETWEEN 2018-01-01 AND 2018-06-01 1行同时满足两个条件 employee.first_name John
AND employee.hire_date BETWEEN 2018-01-01 AND 2018-06-01 在没有条件过滤的情况下EXPLAIN会产生如下输出
----------------------------------------------------------------------------
| id | table | type | possible_keys | key | ref | rows | filtered |
----------------------------------------------------------------------------
| 1 | employee | ref | name,h_date,dept | name | const | 8 | 100.00 |
| 1 | department | eq_ref | PRIMARY | PRIMARY | dept_no | 1 | 100.00 |
----------------------------------------------------------------------------
对于employee名称索引上的访问方法会拾取与名称“John”匹配的8行。没有进行筛选已筛选为100%因此所有行都是下一个表的前缀行前缀行数为行×已筛选8×100%8。
通过条件筛选优化器还会考虑WHERE子句中访问方法未考虑的条件。在这种情况下优化器使用启发式方法来估计employee.hire_date上的BETWEEN条件的过滤效果为16.31%。因此EXPLAIN产生如下输出
----------------------------------------------------------------------------
| id | table | type | possible_keys | key | ref | rows | filtered |
----------------------------------------------------------------------------
| 1 | employee | ref | name,h_date,dept | name | const | 8 | 16.31 |
| 1 | department | eq_ref | PRIMARY | PRIMARY | dept_no | 1 | 100.00 |
---------------------------------------------------------------------------- 现在前缀行数是行×过滤8×16.31%1.3这更能反映实际数据集。
通常优化器不会计算最后一个联接表的条件过滤效果前缀行数减少因为没有下一个表可以将行传递到。
EXPLAIN出现异常为了提供更多信息将计算所有联接表的过滤效果包括最后一个表。 要控制优化器是否考虑其他过滤条件请使用optimizer_switch系统变量的condition_fanout_filter标志请参阅“可切换优化”。
默认情况下会启用此标志但可以禁用此标志以抑制条件筛选例如如果发现某个特定查询在没有条件筛选的情况下可以获得更好的性能。
如果优化器高估了条件筛选的效果则性能可能比不使用条件筛选时更差。
在这种情况下这些技术可能有助于 如果列没有索引请对其进行索引这样优化器就可以获得有关列值分布的一些信息并可以改进其行估计值。 同样如果没有可用的列直方图信息则生成直方图参见第10.9.6节“优化器统计”。 更改联接顺序。实现这一点的方法包括联接顺序优化器提示请参阅第10.9.3节“optimizer提示”、SELECT之后的STRIGHT_join以及STRIGHT_ join联接运算符。 禁用会话的条件筛选 SET optimizer_switch condition_fanout_filteroff; 或者对于给定的查询使用优化器提示 SELECT /* SET_VAR(optimizer_switch condition_fanout_filteroff) */ ...