nodejsmysql优化查询
我正在nodejs v8.9.4中使用mysql2模块。 这是我的函数,用于从满足以下条件的消息队列中获取消息: 状态==0 如果状态==1的botId计数小于10 如果在botId+chatId的等待表中重试\u,且仅botId小于NOWtimestamp 如果没有状态==1的相同chatId 目前,我删除了2个where,查询时间恢复正常nodejsmysql优化查询,mysql,node.js,performance,left-join,Mysql,Node.js,Performance,Left Join,我正在nodejs v8.9.4中使用mysql2模块。 这是我的函数,用于从满足以下条件的消息队列中获取消息: 状态==0 如果状态==1的botId计数小于10 如果在botId+chatId的等待表中重试\u,且仅botId小于NOWtimestamp 如果没有状态==1的相同chatId 目前,我删除了2个where,查询时间恢复正常 q.botId NOT IN (select ...) q.chatId NOT IN (select ...) 所以这两个where查询是阻塞点,需要
q.botId NOT IN (select ...)
q.chatId NOT IN (select ...)
所以这两个where查询是阻塞点,需要修复。不在选择中。。。很难优化
或者无法优化
在ORDER BY中,混合DESC和ASC在8.0之前不使用索引。考虑将ASC更改为DEC。此后,索引优先级、ID可能会有所帮助。
什么是${filterActiveMessageIds}
中不需要GROUP BY
NOT IN ( SELECT q3.chatId
from bot_message_queue q3
where q3.status=1
group by q3.chatId )
按此顺序排列的INDEXstatus、chatid将有利于该子查询
索引状态,按此顺序排列
有关创建索引的详细信息:
在这种情况下,我将用NOT EXISTS替换NOT IN子查询,因为它可以执行得更好。
将订单切换为所有描述或所有ASC
因此,要优化查询,首先,添加以下索引:
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_status_botid_chatid_priori_id` (`status`,`botId`,`chatId`,`priority`,`id`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_priority_id` (`priority`,`id`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_botid_status` (`botId`,`status`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_chatid_status` (`chatId`,`status`);
ALTER TABLE `bot_message_queue_wait` ADD INDEX `bot_message_queue_wa_idx_chatid_botid` (`chatId`,`botId`);
现在,您可以尝试运行此查询。请注意,我已将order by更改为all DESC,因此如果需要,您可以将其更改为ASC:
SELECT
bot_message_queue.*
FROM
bot_message_queue q
LEFT JOIN
bot_message_queue_wait w
ON q.botId = w.botId
AND q.chatId = w.chatId
LEFT JOIN
bot_message_queue_wait w2
ON q.botId = w2.botId
AND w2.chatId = 0
WHERE
q.status = 0
AND NOT EXISTS (
SELECT
1
FROM
bot_message_queue AS q21
WHERE
q21.status = 1
AND q.botId = q21.botId
GROUP BY
q21.botId
HAVING
COUNT(q21.botId) > ?
ORDER BY
NULL
)
AND NOT EXISTS (
SELECT
1
FROM
bot_message_queue AS q32
WHERE
q32.status = 1
AND q.chatId = q32.chatId
GROUP BY
q32.chatId
ORDER BY
NULL
)
AND (
w.retry_after IS NULL
OR w.retry_after <= ?
)
AND (
w2.retry_after IS NULL
OR w2.retry_after <= ?
)
ORDER BY
q.priority DESC,
q.id DESC LIMIT 1
如果这个DDL有一些测试数据,帮助会容易得多。@JitendraSoftgrid不能使用内部联接,因为不是T1中的所有行在T2中都有匹配的行,内部联接将忽略这些行,但这不是我想要的want@Exlord,很抱歉,我一眼就没注意到这些情况。我修改了索引和查询建议。请再试一次并提供反馈。我首先需要最旧的条目,这样q.id DESC就不起作用了。它必须是ASC。Ans NOT EXIST子查询对我也不起作用,因为子查询是根据返回值筛选主查询的,它不可能是简单的true/false@Exlord,请随意将其更改为ASC。关于notexists部分,这个替代方法相当于原始查询中的notin语句,因为我在子查询中添加了相关的条件。那为什么不行呢?查询不返回相同的结果吗?
q.botId NOT IN (select ...)
q.chatId NOT IN (select ...)
NOT IN ( SELECT q3.chatId
from bot_message_queue q3
where q3.status=1
group by q3.chatId )
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_status_botid_chatid_priori_id` (`status`,`botId`,`chatId`,`priority`,`id`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_priority_id` (`priority`,`id`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_botid_status` (`botId`,`status`);
ALTER TABLE `bot_message_queue` ADD INDEX `bot_message_queue_idx_chatid_status` (`chatId`,`status`);
ALTER TABLE `bot_message_queue_wait` ADD INDEX `bot_message_queue_wa_idx_chatid_botid` (`chatId`,`botId`);
SELECT
bot_message_queue.*
FROM
bot_message_queue q
LEFT JOIN
bot_message_queue_wait w
ON q.botId = w.botId
AND q.chatId = w.chatId
LEFT JOIN
bot_message_queue_wait w2
ON q.botId = w2.botId
AND w2.chatId = 0
WHERE
q.status = 0
AND NOT EXISTS (
SELECT
1
FROM
bot_message_queue AS q21
WHERE
q21.status = 1
AND q.botId = q21.botId
GROUP BY
q21.botId
HAVING
COUNT(q21.botId) > ?
ORDER BY
NULL
)
AND NOT EXISTS (
SELECT
1
FROM
bot_message_queue AS q32
WHERE
q32.status = 1
AND q.chatId = q32.chatId
GROUP BY
q32.chatId
ORDER BY
NULL
)
AND (
w.retry_after IS NULL
OR w.retry_after <= ?
)
AND (
w2.retry_after IS NULL
OR w2.retry_after <= ?
)
ORDER BY
q.priority DESC,
q.id DESC LIMIT 1