我有一个查询耗时太长(>5分钟)并造成死锁

virt_assist_bandwidth_incoming有1115501行

虚拟辅助带宽传入媒体有25752行

我不认为这是晚餐大桌子.

询问:

SELECT *
FROM virt_assist_bandwidth_incoming i
     LEFT JOIN virt_assist_bandwidth_incoming_media m ON m.messageID = i.messageID
WHERE i.from_id = '0'
  AND i.sms_type = 0
ORDER BY received DESC

-

CREATE TABLE `virt_assist_bandwidth_incoming` (                                                    
 `messageID` varchar(55) DEFAULT NULL,                                                    
 `from` char(15) DEFAULT NULL,                                                    
 `eventType` varchar(5) DEFAULT NULL,                                                    
 `text` varchar(512) DEFAULT NULL,                                                    
 `time` varchar(25) DEFAULT NULL,                                                    
 `to` char(10) DEFAULT NULL,                                                    
 `state` varchar(15) DEFAULT NULL,                                                    
 `messageURL` varchar(105) DEFAULT NULL,                                                    
 `applicationId` varchar(25) DEFAULT NULL,                                                    
 `direction` varchar(10) DEFAULT NULL,                                                    
 `vid` int(11) DEFAULT NULL,                                                    
 `from_id` int(11) DEFAULT NULL,                                                    
 `received` timestamp NULL DEFAULT NULL,                                                    
 `process_status` varchar(255) DEFAULT NULL,                                                    
 `sms_type` tinyint(4) DEFAULT NULL,                                                    
 `acted_upon` tinyint(4) DEFAULT '0',                                                    
 KEY `vidx_1` (`messageID`),                                                    
 KEY `vidx_2` (`vid`),                                                    
 KEY `vidx_3` (`sms_type`),                                                    
 KEY `vidx_4` (`from_id`),                                                    
 KEY `vidx_5` (`time`,`messageID`),                                                    
 KEY `vidx_6` (`vid`,`process_status`,`acted_upon`),                                                    
 KEY `vidx_7` (`vid`,`process_status`,`time`),                                                    
 KEY `vidx_8` (`from_id`,`sms_type`,`messageID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

-

CREATE TABLE `virt_assist_bandwidth_incoming_media` (
 `messageID` varchar(55) DEFAULT NULL,
 `media` varchar(512) DEFAULT NULL,
KEY `vabimind_1` (`messageID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

当我做一个解释计划时

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE i ref "virt_assist_bandwidth_incoming_sms_type_index,virt_assist_bandwidth_incoming_from_id_index,vidx_8" vidx_8 7 "const,const" 28670 100 Using temporary; Using filesort
1 SIMPLE m ALL 25761 100 Using where; Using join buffer (Block Nested Loop)

我试着添加了建议的索引

查询仍然需要20分钟,返回的记录计数为190682

谢谢你的帮助或见解

推荐答案

最大的问题是您的表使用不同的字符集.这将防止第二个表的连接使用索引.

我的建议是:

ALTER TABLE virt_assist_bandwidth_incoming CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE virt_assist_bandwidth_incoming_media CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

utf8mb4是当前版本MySQL中的默认字符集.我认为你需要其他角色集是不寻常的.

实际上,你所连接的两个列中的排序规则需要相同.当然,它们也需要是相同的字符集,以具有相同的排序.

进一步的优化可以是添加一个索引来消除文件命令.

ALTER TABLE virt_assist_bandwidth_incoming ADD INDEX vidx_9 (from_id, sms_type, received);

我还建议使用InnoDB超过MyISAM.自2010年以来,InnoDB是MySQL中的默认存储引擎,它比MyISAM有很多优势,包括性能.我的答案是MyISAM versus InnoDB

ALTER TABLE virt_assist_bandwidth_incoming ENGINE=InnoDB;
ALTER TABLE virt_assist_bandwidth_incoming_media ENGINE=InnoDB;

Mysql相关问答推荐

MySQL:一个查询中的SELECT语句,用于从一个表中检索所有数据,并仅从另一个表中检索一个数据

JPA对具有动态键和动态值的JSON列的原生查询

为什么 MAX 函数通过调用在 group 中生成正确的结果

Mysql,从两个不同的表中添加原始数据,从第一个表中获取所有内容,仅从第二个表中获取curdate内容

获取每个参数的记录,不重复

如何将数据导入MySQL中的master/replica struct

如何在 axios 请求中将更新的设置状态值作为参数传递

如何让连续 3 周或以上的用户有订单?

需要按总金额检索前 3 个供应商,每个类别 - 子类别

从 mysql RDS 导出数据以导入 questDb

MySQL 将分组 JSON Select 转换为单个 JSON 对象

在 postgresql 中实现 UML 类:创建类型与创建表

用两个新列制作表格,按偶数或奇数对另一列进行分类,并将一个类别中的所有偶数和奇数相加

此插页中的X是什么> X'3C2F756C3E'

动态创建内联 SQL 表(用于排除左连接)

PHP,MySQL 错误:列计数与第 1 行的值计数不匹配

在mysql中将纪元数转换为人类可读的日期

是否可以在内部连接期间重命名连接列?

Ubuntu 中的 MySQL JDBC jar 文件在哪里?

在 MySQL 中的子查询上使用 GROUP_CONCAT