mysql 关联查询问题,1.5W *3W数据的关联;
sqlserver 查询2S,mysql查询4min
-- show create table table_1
CREATE TABLE `table_1` (
`id` int NOT NULL AUTO_INCREMENT,
`flag_id` int NOT NULL,
`oper1` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '操作',
`oper1_time` datetime(3) DEFAULT NULL COMMENT '时间',
`x` int NOT NULL,
`y` int NOT NULL,
`status` varchar(20) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `ix_xy` (`flag_id`,`oper1`,`oper1_time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16555 DEFAULT CHARSET=latin1
-- show create table table_2
CREATE TABLE `table_2` (
`id` int NOT NULL AUTO_INCREMENT,
`flag_id` int NOT NULL,
`oper2` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '操作',
`deviceid` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL ,
`delay` int NOT NULL ,
`return` tinyint(1) NOT NULL ,
`oper2_time` datetime(3) NOT NULL COMMENT '操作时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `ix_ld` (`flag_id`,`oper2`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=133131 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
sql 语句如下图
SELECT t.id
,COUNT(t2.id) t2_num
FROM (
SELECT a.id,a.flag_id
,a.oper1_time begin_time
,LEAD(oper1_time,1)OVER(ORDER BY oper1_time) end_time
FROM table_1 a
WHERE a.flag_id = 6
AND a.oper1 = "操作1_1"
-- AND oper1_time BETWEEN '2022-09-03 14:52:54.320' AND '2022-09-03 14:54:34.457'
)t
INNER JOIN table_2 t2 ON t2.flag_id = t.flag_id AND t2.oper2 = "操作2_2"
AND t2.oper2_time BETWEEN t.begin_time AND t.end_time
GROUP BY t.id
执行计划
关联语句在哪呢
要用left join,不要写笛卡尔积
这么点数据那么慢,保证是写了笛卡尔积了,这一乘上亿了不慢才怪
sql数据库会自动将笛卡尔积优化成左外连接,但是mysql属于sql的低配版,没那么多功能
你这需要建立索引了。你这子表查询,然后再关联另1个表,在当做子表,再查询。这个几乎就是全表扫描了。速度慢很正常。
把你的SQL复制粘贴出来吧。图片看不清。
sql server做了缓存的,一般来讲效果会略高于mysql ,但不会相差像你说的这么多:
首先,key_id也要建立索引,看你的图片后面那几个字段是建了的是么。
其次,可考虑使用mysql内存表加快速度
确保你mysql写法正常走索引,可以把数据发出来,帮你优化一下sql写法