具有不同执行计划的 MySQL Master 和 Slave

标签 mysql sql-execution-plan

我有一个复杂的 MySQL 查询,它连接三个表并将一个表自连接到自身。

有一个 Master 和一个 Slave 具有相同的数据和索引。与 Slave 相比,Master 是一个强大的盒子,但查询在 Slave 上的运行速度要快 10 倍(在 Master 的轻负载期间)。

执行计划大不相同。

Master execution plan
1, 'SIMPLE', 'table3_', 'const', 'PRIMARY', 'PRIMARY', '12', 'const', 1, 100.00, 'Using temporary; Using filesort'
1, 'SIMPLE', 'table2_', 'ref', 'PRIMARY,FK376E02E910238FCA', 'FK376E02E910238FCA', '13', 'const', 105, 100.00, 'Using where'
1, 'SIMPLE', 'table0_', 'ref', 'FK57012F937DD0DC02,FK57012F9398CD28D0', 'FK57012F9398CD28D0', '13', 'table2_.ID', 1515, 100.00, 'Using where'
1, 'SIMPLE', 'table1_', 'eq_ref', 'PRIMARY,FKE7E81F1ED170D4C9', 'PRIMARY', '8', 'table0_.FK_ID', 1, 100.00, 'Using where'

Slave execution plan
1, 'SIMPLE', 'table3_', 'const', 'PRIMARY', 'PRIMARY', '12', 'const', 1, 100.00, 'Using filesort'
1, 'SIMPLE', 'table1_', 'ref', 'PRIMARY,FKE7E81F1ED170D4C9', 'FKE7E81F1ED170D4C9', '9', 'const', 187398, 100.00, 'Using where'
1, 'SIMPLE', 'table0_', 'ref', 'FK57012F937DD0DC02,FK57012F9398CD28D0', 'FK57012F937DD0DC02', '9', 'table1_.ID', 1, 100.00, 'Using where'
1, 'SIMPLE', 'table2_', 'eq_ref', 'PRIMARY,FK376E02E910238FCA', 'PRIMARY', '12', 'table0_.FK_ID', 1, 100.00, 'Using where'

表以不同的顺序处理,主数据库同时使用临时表和文件排序,而从数据库仅使用文件排序。

哪些因素会导致执行时间差异如此之大的不同计划?

更新:

这可能与索引统计信息有关吗?我计划在低容量期间在 Master 上运行 ANALYZE TABLE。 SHOW INDEX 显示 Master 和 Slave 之间的一些键的基数非常不同。

最佳答案

MySQL 根据收集的统计信息优化查询。

查看您的输出,您会发现它们使用了不同的键,您可能需要添加键提示甚至强制键

FROM table2_JOIN

应该变成

FROM table2_ USE KEY('FK376E02E910238FCA') JOIN

或强制键

关于具有不同执行计划的 MySQL Master 和 Slave,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1909653/

相关文章:

mysql - 调用存储过程在 MySQL 5.5 的所有列中插入 NULL

MySQL 在数据库数组字段中搜索值(整数或字符串)

php - MYSQL 根据条件 1 联接,否则根据条件 2 联接

database - 防止 PostgreSQL 有时选择错误的查询计划

postgresql - 使用 PostgreSQL 进行简单但缓慢的 SQL 查询

c++ - 未解析的符号:sql::mysql::get_driver_instance(void)

php - 具有隐私的 Cakephp 复杂查询

sql - 关于如何读取SQL执行计划的问题

PostgreSQL 手动更改查询执行计划以强制使用排序和顺序访问而不是全扫描

Postgresql索引seq扫描1亿行