为什么SQL选择连接索引不一致?

时间:2018-04-20 21:36:36

标签: mysql sql join indexing

我在三列上有两个表之间的连接。连接需要几个小时才能完成,所以我在每个表的所有三列上添加了一个复合索引。然后,有时连接会非常快,有时它仍然会很慢。

使用EXPLAIN,我注意到当它选择使用复合索引进行连接时速度很快,而当它只在一个列上选择索引时速度很慢。但这些运行中的每一个都使用相同的数据

SQL中是否存在随机性选择使用哪个索引?为什么会不一致?

如果有帮助:它是从python中的pandas查询的MySQL数据库。

1 个答案:

答案 0 :(得分:1)

问:SQL中是否存在随机性选择使用哪个索引?

本身并不涉及随机性。优化器利用表和索引统计(行数和基数)以及查询中的谓词来开发估计值,例如:需要检索的行数。

MySQL还评估每个可能的访问计划的连接操作,排序操作等的成本(例如,使用哪个索引,访问表中的哪个顺序)以计算每个计划的估计成本。

然后优化器会比较成本,并使用成本最低的计划。有一些参数(MySQL系统变量)会影响成本估算。 (例如,调整I / O操作的预期成本。)

问:为什么会不一致?

对于InnoDB表,收集统计信息会产生一些随机性。 InnoDB使用采样技术,进行深度潜水。进入一小组"随机"页面。这些样本页面的结果被推断为整个表格的估计值。

一些InnoDB调整参数(MySQL系统变量)影响(增加/减少)收集统计信息时采样的页数。采样较少数量的页面可能更快,但较小的样本使得样本集更可能不完全代表整个表格。使用大量样本会在一定程度上缓解这种情况,但采样时间会更长。这是一种权衡。

请注意,当使用DML操作更改表中10%的行时,InnoDB会自动重新收集统计信息。 (在某些情况下,可能无法触发自动收集统计信息,例如,创建新的(空)表并使用LOAD DATA语句填充它,这可能导致无法收集统计信息。)

因此,观察到的行为最可能的解释是,在不同的时间,优化器可以使用不同的统计信息。

请注意,通过在SQL文本中包含提示,可以影响优化器选择使用特定索引的计划。我们通常不需要这样做,我们也不想这样做。但在某些情况下,优化者选择效率低下的计划,我们可以帮助您制定更好的计划。

一些参考资料(来自MySQL 5.7参考手册)

https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-performance-optimizer-statistics.html