【发布时间】:2016-06-26 00:24:51
【问题描述】:
我在 AWS 上通过 NodeJS 开发了一个应用程序,该应用程序具有关联的 MySQL RDS 数据库(服务器类:db.r3.large - 引擎:InnoDB)。我们遇到了性能问题,当我们(同时)执行同时查询时,数据库在完成最后一个查询后返回结果,而不是在每个查询完成后返回结果。
因此,举个例子:如果我们执行一个进程,它有 10 个同时查询,每个查询 3 秒,我们会在大约 30 秒时开始接收结果,并且我们希望在第一个查询完成时(3 秒)开始接收。
似乎数据库正在接收查询并将它们排成队列。
我有点迷路了,因为我更改了代码的几处(单独的连接、池连接等)和 AWS 的设置,但似乎并没有改善结果。
TableA(13M 记录)架构:
CREATE TABLE `TableA` (
`columnA` int(11) NOT NULL AUTO_INCREMENT,
`columnB` varchar(20) DEFAULT NULL,
`columnC` varchar(15) DEFAULT NULL,
`columnD` varchar(20) DEFAULT NULL,
`columnE` varchar(255) DEFAULT NULL,
`columnF` varchar(255) DEFAULT NULL,
`columnG` varchar(255) DEFAULT NULL,
`columnH` varchar(10) DEFAULT NULL,
`columnI` bigint(11) DEFAULT NULL,
`columnJ` bigint(11) DEFAULT NULL,
`columnK` varchar(5) DEFAULT NULL,
`columnL` varchar(50) DEFAULT NULL,
`columnM` varchar(20) DEFAULT NULL,
`columnN` int(1) DEFAULT NULL,
`columnO` int(1) DEFAULT '0',
`columnP` datetime NOT NULL,
`columnQ` datetime NOT NULL,
PRIMARY KEY (`columnA`),
KEY `columnB` (`columnB`),
KEY `columnO` (`columnO`),
KEY `columnK` (`columnK`),
KEY `columnN` (`columnN`),
FULLTEXT KEY `columnE` (`columnE`)
) ENGINE=InnoDB AUTO_INCREMENT=13867504 DEFAULT CHARSET=utf8;
TableB(15M 记录)架构:
CREATE TABLE `TableB` (
`columnA` int(11) NOT NULL AUTO_INCREMENT,
`columnB` varchar(50) DEFAULT NULL,
`columnC` varchar(50) DEFAULT NULL,
`columnD` int(1) DEFAULT NULL,
`columnE` datetime NOT NULL,
`columnF` datetime NOT NULL,
PRIMARY KEY (`columnA`),
KEY `columnB` (`columnB`),
KEY `columnC` (`columnC`)
) ENGINE=InnoDB AUTO_INCREMENT=19153275 DEFAULT CHARSET=utf8;
查询:
SELECT COUNT(*) AS total
FROM TableA
WHERE TableA.columnB IN (
SELECT TableB.columnC
FROM TableB
WHERE TableB.columnB = "3764301"
AND TableB.columnC NOT IN (
SELECT field
FROM table
WHERE table.field = 10
AND TableB.columnC NOT IN (
SELECT field
FROM table
WHERE table.field = 10
AND TableB.columnC NOT IN (
SELECT field
FROM table
WHERE table.field = 10
AND TableB.columnC NOT IN (
SELECT field
FROM table
WHERE table.field = 10
)
AND columnM > 2;
- 2s 1 次执行返回
- 10 次执行会在 20 秒内返回第一个结果,然后返回另一个结果。
要查看查询是否正在运行,我使用的是“SHOW FULL PROCESSLIST”,并且查询大部分时间都处于“正在发送数据”状态。
这不是查询的性能问题,而是数据库的重复问题。即使是像“SELECT COUNT(*) FROM TableA WHERE columnM = 5”这样非常简单的查询也有同样的问题。
更新
仅出于测试目的,我将查询减少到只有一个子查询条件。两个结果都有 65k 条记录。
-- USING IN
SELECT COUNT(*) as total
FROM TableA
WHERE TableA.columnB IN (
SELECT TableB.columnC
FROM TableB
WHERE TableB.columnB = "103550181"
AND TableB.columnC NOT IN (
SELECT field
FROM tableX
WHERE fieldX = 15
)
)
AND columnM > 2;
-- USING EXISTS
SELECT COUNT(*) as total
FROM TableA
WHERE EXISTS (
SELECT *
FROM TableB
WHERE TableB.columnB = "103550181"
AND TableA.columnB = TableB.columnC
AND NOT EXISTS (
SELECT *
FROM tableX
WHERE fieldX = 15
AND fieldY = TableB.columnC
)
)
AND columnM > 2;
-- Result
Query using IN : 1.7 sec
Query using EXISTS : 141 sec (:O)
使用 IN 或 EXISTS 问题是一样的,当我多次执行此查询时,数据库会出现延迟,并且响应会在很长一段时间后出现。 示例:如果一个查询响应在 1.7 秒内,如果我执行此查询 10 次,第一个结果是在 20 秒内。
【问题讨论】:
-
您应该考虑至少发布查询和表格概述。没有细节就无法知道。它们中的任何一个都涉及更新吗?您系统的任何其他部分是否在数据库中发生更新?尝试运行
SHOW FULL PROCESSLIST并查看是否有任何查询锁定了行或耗时过长。 -
谢谢罗德里戈,我在我的问题中添加了更多细节。
-
运行查询时
tx_isolation是什么?他们在BEGIN...COMMIT交易中吗?还是使用autocommit=1运行? -
谢谢瑞克。 tx_isolation 是 REPEATABLE-READ 并且自动提交是 1
-
现在你需要
INDEX(fieldX, fieldY)和INDEX(columnB, columnC)。
标签: mysql node.js amazon-web-services amazon-rds