我的子查询为执行时间增加了20秒.我怎样才能加快速度?

Cra*_*aig 7 php mysql sql database phpmyadmin

我有一个已发送短信的表格,该短信必须加入到送达回执表中才能获得最新的短信状态.

有997,148条发送短信.

我正在运行此查询:

SELECT
    m.id,
    m.user_id,
    m.api_key,
    m.to,
    m.message,
    m.sender_id,
    m.route,
    m.submission_reference,
    m.unique_submission_reference,
    m.reason_code,
    m.timestamp,
    d.id AS dlrid,
    d.dlr_status
FROM
    messages_sent m
LEFT JOIN
    delivery_receipts d
ON
    d.message_id = m.id
AND
    d.id = (SELECT MAX(id) FROM delivery_receipts WHERE message_id = m.id)
Run Code Online (Sandbox Code Playgroud)

返回997,148个结果,包括每条消息的最新状态.

这需要22.8688秒来执行.

这是SQL messages_sent:

CREATE TABLE IF NOT EXISTS `messages_sent` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`api_key` varchar(40) NOT NULL,
`to` varchar(15) NOT NULL,
`message` text NOT NULL,
`type` enum('sms','mms') NOT NULL DEFAULT 'sms',
`sender_id` varchar(15) NOT NULL,
`route` tinyint(1) unsigned NOT NULL,
`supplier` tinyint(1) unsigned NOT NULL,
`submission_reference` varchar(40) NOT NULL,
`unique_submission_reference` varchar(40) NOT NULL,
`reason_code` tinyint(1) unsigned NOT NULL,
`reason` text NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `api_key` (`api_key`),
KEY `sender_id` (`sender_id`),
KEY `route` (`route`),
KEY `submission_reference` (`submission_reference`),
KEY `reason_code` (`reason_code`),
KEY `timestamp` (`timestamp`),
KEY `to` (`to`),
KEY `unique_submission_reference` (`unique_submission_reference`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1000342 ;
Run Code Online (Sandbox Code Playgroud)

并为delivery_receipts:

CREATE TABLE IF NOT EXISTS `delivery_receipts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`message_id` int(10) unsigned NOT NULL,
`dlr_id` bigint(20) unsigned NOT NULL,
`dlr_status` tinyint(2) unsigned NOT NULL,
`dlr_substatus` tinyint(2) unsigned NOT NULL,
`dlr_final` tinyint(1) unsigned NOT NULL,
`dlr_refid` varchar(40) NOT NULL,
`dlr_phone` varchar(12) NOT NULL,
`dlr_charge` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `message_id` (`message_id`),
KEY `dlr_status` (`dlr_status`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1468592 ;
Run Code Online (Sandbox Code Playgroud)

这是一个EXPLAINSQL:

在此输入图像描述

krl*_*mlr 0

速度下降看起来很大,但如果你需要坚持这个查询,恐怕没有太大的改进空间。

其中一个问题是报告d.dlr_status。尝试从报告的列列表中删除它,看看查询时间是否有所改善。

如果所有内容都存储在messages_sent. 这不再是 NF,但如果您需要性能,它是一个选择。要实现此目的,请在 中创建id和dlr_status列并向中messages_sent添加适当的INSERT和UPDATE触发器。触发器将更新相应的列——这是查询时间和更新时间之间的权衡。DELETEdelivery_receiptsmessages_sent