尽管有索引,MySQL的select查询性能仍然很差
我们有两个表、消息和客户合同,定义如下:尽管有索引,MySQL的select查询性能仍然很差,mysql,Mysql,我们有两个表、消息和客户合同,定义如下: create table customercontracts (customer_id varchar(20), contractnumber varchar(20), role varchar(4)); alter table customercontracts add index contractnumber (cont
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 );
还有这样一个查询:
select * from messages m, customercontracts c
where m.customer_id = '12345'
and c.contractnumber = m.contractnumber;
大约有4000条消息行和3000000条customercontracts行。尽管customer_id和contractnumber上都有索引,但执行上述查询大约需要4秒钟。”Explain'(在MySQL Workbench中)显示了对customercontracts的完整表扫描和628000的查询成本
问题:
1) 当我在customercontracts上有索引时,为什么要对这些表进行完整的表扫描?性能不佳的原因是什么
< P > 2)我如何重写这个查询是性能?< p>我会考虑添加一个整数“id”字段作为客户合同的主键,然后通过Cuffer-CurrassSid而不是消息表中的CalcType编号来引用。您应该已经看到性能的改进
或者,您可以尝试在两个contractnumber列上添加全文索引,但我建议您选择第一个选项。我建议您在消息表customer\u id、contractnumber和check performance上尝试使用复合索引,尽量避免在select中使用* 我想我终于找到了答案。上面我的示例表创建代码没有显示字符编码(这是我的一个学习,不要使用快捷方式示例代码!)。事实证明,customercontacts表是用utf8编码的,而messages表是用utf8mb4编码的 连接不同字符编码的列时,不能使用索引。
这回答了“为什么会发生这种情况”。为了解决这个问题,我们修改了utf8m4表,将索引列的编码降级为utf8(同时将表的其余部分的编码保持为utf8mb4)。这对我们来说有固定的性能。如果您执行以下命令,请验证MySQL是否使用索引:*从customercontracts c中选择*,其中c.contractnumber=VALIDNUMBER**主键不清楚。请澄清-抱歉,表格定义已简化。主键是另一列(不包括)。合同号和客户id是单独的非唯一键(使用BTREE)。两个表上的数据高度唯一。@BerndBuffen-是,该语句使用索引