【问题标题】:Why does MySQL pick the wrong index in JOIN query?为什么 MySQL 在 JOIN 查询中选择错误的索引?
【发布时间】:2023-03-18 15:29:01
【问题描述】:

我使用了一个简单的JOIN 查询,但是 MySQL 在EXPLAIN 计划中一直显示错误的索引。

它在不参与查询的列上选择一个索引。

查询基于主键。我尝试删除索引,但优化器选择了另一个不相关的索引。

在我的例子中,表 a 保存了约 250 万条记录,表 b 保存了约 500 万条记录。 a 中的每条记录在 b 中都有 ~2 条记录。

我正在使用 MySql 5.6。

我在桌子上做了ANALYZECHECK

查询大约需要 70 秒,它使用了错误的索引并执行了嵌套循环,为什么?

SELECT 
IFNULL(SUM(a.val),0) as total
FROM a , b
where a.id = b.a_id;

1   SIMPLE  a   index   PRIMARY idx_a_c_id  5       2406691 Using index
1   SIMPLE  tv  ref idx_a_id idx_a_id   4   capb_1.a.id 1

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'spd_transaction', 'index', 'PRIMARY', 'idx_a_c_id', '5', NULL, '2406691', 'Using index'
'1', 'SIMPLE', 'tv', 'ref', 'idx_a_id', 'idx_a_id', '4', 'a.id', '1', NULL

【问题讨论】:

  • 你好,a 是 spd_transaction? b 看电视?
  • 你能把你想加入的表的 CREATE 语句放在一起吗?恕我直言,也不推荐他们编写连接的方式。
  • 创建表A (id int(11) NOT NULL, p_id int(11) DEFAULT NULL, date1 datetime NOT NULL, c_id int(11) NOT NULL , acc_id int(11) DEFAULT NULL, co_id int(11) DEFAULT NULL, PRIMARY KEY (id), KEY idx_c_id (c_id), KEY idx_acc_id (acc_id), KEY fk_co_id (co_id), ) ENGINE=InnoDB 默认字符集=utf8;
  • 创建表b (id int(11) NOT NULL, a_id int(11) NOT NULL, another_id int(11) NOT NULL, val decimal(32 ,6) 默认NULL,主键(id),唯一键uk_a_id_another_ida_id,another_id),约束fk_a_id外键(a_id)参考a(@986) DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 什么是'idx_a_c_id'?我在表定义中找不到。您可以在强制使用主键时发布EXPLAIN 吗?

标签: mysql performance join explain


【解决方案1】:

1) 查看 SQL 的性质(无谓词),我建议使用提示(我不经常鼓励)忽略索引并强制数据库引擎使用 FTS(全表扫描)。

在这种情况下,FTS 会比使用任何索引更好。

SELECT 
IFNULL(SUM(a.val),0) as total
FROM a , b USE INDEX /* Specify no index here to ignore index and force FTS*/
where a.id = b.a_id;

我不建议删除表上的索引,因为我不知道它们在您的应用程序中的其他地方使用。

2) 我还建议删除表“B”上的 JOIN,因为 SQL 没有在输出中使用大表的这种昂贵的 JOIN。

SELECT 
IFNULL(SUM(a.val),0) as total
FROM a USE INDEX /* Specify no index here to ignore index and force FTS*/
;

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2020-09-14
    • 2021-04-19
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多