在同步查询的情况下对MySQL RDS性能的挑战

我有一个通过AWS上的NodeJS开发的应用程序,该应用程序与MySQL RDS数据库(服务器类:db.r3.large – Engine:InnoDB)相关联。 我们遇到性能问题,当我们同时执行同时查询时,数据库在完成最后一个查询后返回结果,而不是在每个查询完成后返回结果。

所以,举个例子:如果我们执行一个有10个同时查询的进程,每个查询的时间间隔为3秒,我们开始接收结果的时间约为30秒,我们希望在第一个查询完成(3秒)时开始接收数据。

看来,数据库正在接收查询并对其进行排队。

我有点迷失在这里,因为我改变了代码和AWS的几个东西(单独的连接,池连接等),但似乎并没有改善结果。

表A(13Mlogging)架构:

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; 

表B(15Mlogging)架构:

 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; 
  • 1秒内执行返回
  • 10次​​执行会在20秒内返回第一个结果,在此之后返回另一个结果。

要查看查询正在运行,我正在使用“SHOW FULL PROCESSLIST”,查询大部分时间都是状态“发送数据”。

这不是关于查询的性能问题,而是数据库重复发生的问题。 即使是一个非常简单的查询,如“SELECT COUNT(*)FROM TableA WHERE columnM = 5”也有同样的问题。

UPDATE

仅用于testing目的,我减less查询只有一个子查询条件。 两项结果都有65k的logging。

 -- 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秒。

build议1

NOT IN ( SELECT ... )更改为NOT EXISTS ( SELECT * ... ) 。 (您可能需要稍微更改WHERE子句。

 AND TableB.columnC NOT IN ( SELECT field FROM table WHERE table.field = 10 

– >

 AND NOT EXISTS ( SELECT * FROM table WHERE field = TableB.columnC ) 

table需要一个field的索引。

IN ( SELECT ... )performance很差。 EXISTS更好的优化。

build议2

要处理并发性,请考虑在查询之前执行SET SESSION TRANSACTION READ UNCOMMITTED 。 这可以保持一个连接不干扰另一个连接。

build议3

向我们展示EXPLAIN ,索引( SHOW CREATE TABLE )(你给的东西是不够的),和WHERE子句,这样我们可以批评索引。

build议4

可能会有助于TableB具有一个复合INDEX(ColumnB, ColumnC)的顺序。

我可以在这里看到的是巨大的临时表正在为每个查询构build。 考虑不同的架构。