首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尽管有索引,MySQL的选择查询性能很差

尽管有索引,MySQL的选择查询性能很差
EN

Stack Overflow用户
提问于 2019-03-06 12:46:31
回答 3查看 57关注 0票数 0

我们有两个表、消息和客户合同,定义如下:

代码语言:javascript
复制
create table customercontracts (customer_id varchar(20), 
                                contractnumber varchar(20), 
                                role varchar(4));
alter table customercontracts add index contractnumber (contractnumber);

create table messages (customer_id varchar(20), 
                                contractnumber varchar(20), 
                                message varchar(400));
alter table messages add index contractnumber (contractnumber);
alter table messages add index customer_id (customer_id );

还有这样的查询:

代码语言:javascript
复制
select * from messages m, customercontracts c 
 where m.customer_id = '12345' 
   and c.contractnumber = m.contractnumber;

大约有4,000条消息行和3,000,000条客户合同行。尽管customer_id和契约号都有索引,但上面的查询大约需要4秒才能执行。“Ex平原”(在MySQL工作台中)显示了对客户合同的全表扫描,查询成本为628,000。

问题:

1)当我在这些表上有索引时,为什么会对客户合同进行全表扫描?业绩不佳的原因是什么?

2)如何重写此查询以使其具有表现性?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-07 10:39:24

我想我终于找到了答案。上面的示例表创建代码没有显示字符编码(对我来说是一个学习,不要快捷示例代码!)事实证明,customercontacts表是用utf8编码的,而messages表是用utf8mb4编码的。

当连接不同字符编码的列时,不能使用索引。

这回答了“为什么会发生这种事”。为了解决这个问题,我们修改了utf8m4表,将索引列的编码降级为utf8 (同时将表其余部分的编码保持为utf8mb4)。这对我们来说是固定的表现。

票数 0
EN

Stack Overflow用户

发布于 2019-03-06 13:09:28

我建议在message customer_id上尝试复合索引、契约号和检查性能,尽量避免在select中使用*。

票数 0
EN

Stack Overflow用户

发布于 2019-03-06 13:00:50

我会考虑添加一个整数"id“字段作为customercontracts的主键,然后通过customercontracts_id而不是messages表中的契约号进行引用。你应该已经看到了性能的提高。

或者,您可以尝试在两个合同编号列上添加全文索引,但我建议使用第一个选项。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55023481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档