MySQL太慢了加入查询需要1小时48分钟才能获得30条记录

MySQL太慢了加入查询需要1小时48分钟才能获得30条记录,mysql,sql,Mysql,Sql,我有两张桌子 CREATE TABLE `labels` ( `id` bigint(20) NOT NULL, `user_id` bigint(20) NOT NULL, `print_id` bigint(20) NOT NULL, `template_id` bigint(20) NOT NULL, `type` tinyint(1) NOT NULL, `series` varchar(20) DEFAULT NULL, `confirm` varchar(

我有两张桌子

CREATE TABLE `labels` (
  `id` bigint(20) NOT NULL,
  `user_id` bigint(20) NOT NULL,
  `print_id` bigint(20) NOT NULL,
  `template_id` bigint(20) NOT NULL,
  `type` tinyint(1) NOT NULL,
  `series` varchar(20) DEFAULT NULL,
  `confirm` varchar(20) DEFAULT NULL,
  `views` bigint(20) DEFAULT '0',
  `status` tinyint(1) NOT NULL DEFAULT '0',
  `created_by` bigint(20) NOT NULL,
  `created_at` int(11) DEFAULT NULL,
  `modified_at` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `labels`
  ADD PRIMARY KEY (`id`),
  ADD KEY `id` (`id`,`user_id`,`template_id`,`type`,`series`,
  `confirm`,`status`,`created_at`,`modified_at`),
  ADD KEY `id_2` 
 (`id`,`user_id`,`template_id`,`series`,`status`,`created_at`),
  ADD KEY `id_3` (`id`,`user_id`,`print_id`,`template_id`,`type`,`series`,
 `confirm`,`views`,`status`,`created_by`,`created_at`,`modified_at`),
  ADD KEY `id_4` 
 (`id`,`user_id`,`print_id`,`template_id`,`type`,
 `series`,`confirm`,`views`,`status`,`created_by`,
 `created_at`,`modified_at`);
ALTER TABLE `labels`
  MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
CREATE TABLE `label_relations` (
  `id` bigint(20) NOT NULL,
  `label_id` bigint(20) NOT NULL,
  `type` tinyint(1) NOT NULL,
  `related_id` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `label_relations`
  ADD PRIMARY KEY (`id`),
  ADD KEY `listIndex` (`id`,`label_id`,`type`,`related_id`);
ALTER TABLE `label_relations`
  MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
标签有1337000条记录 label_关系有227000条记录 label_日志有215000条记录

我运行这个查询是为了得到与条件的关系

 SELECT `label_logs`.`id` FROM `label_logs`   
 LEFT JOIN `label_relations` AS `Relation` ON (`label_logs`.`label_id` = 
 `Relation`.`label_id`) WHERE `label_logs`.`status` = 1 
 AND `Relation`.`type` = 1  ORDER BY `label_logs`.`created_at` DESC  LIMIT 30;
但这需要30排,1小时48分48.18秒

仅使用标签关系表。。。当我查询join with label_logs是正常的时

以这种方式更改您的label_关系索引

 ADD KEY `listIndex` (`label_id`,`type`,`related_id`);
在您的代码中,label_id之前的id可以使此索引的使用无效

您可能需要相同的标签日志表

您正在查找状态为1的标签日志记录,其中也存在同一标签的标签关系。也许你应该这样写

SELECT id 
FROM label_logs
WHERE status = 1 
AND label_id IN (SELECT label_id FROM label_relations WHERE type = 1)
ORDER BY created_at DESC
LIMIT 30;
为了快速运行查询,我将尝试以下索引:

create index idx1 on label_logs(status, label_id, created_at, id);
create index idx2 on label_logs(label_id, status, created_at, id);
create index idx3 on label_relations(label_id, type);
create index idx4 on label_relations(type, label_id);
然后使用EXPLAIN查看使用了哪些索引,哪些没有

您还可以用EXISTS子句替换上面的IN子句。MySQL过去在中存在性能问题。希望不会了,但谁知道呢

AND EXISTS
 (SELECT * FROM label_relations lr WHERE lr.type = 1 AND lr.label_id = label_logs.label_id)

使用EXPLAIN找出您需要索引的位置。此外,在您获得30条记录之前,整个连接结果都将被排序。您在查询中引用了表_日志,但我看不到此表schemaAs Jens已经说过所有行都已排序。你能试着在索引上排序吗?如果id和created_at的顺序相同,则可以使用该id。。。按标签订购\u logs.id DESC。