2020-02-11 11:47:24 1962次浏览 2条回答 0 悬赏 10 金钱

三张表 连表查询,都有索引,使用 explain 执行计划查看,主表没有用到索引
feed主表 里面数据比较多,一百多万条,还在不断增加

explain 
SELECT
	`feed`.*
FROM
	`feed`
LEFT JOIN `group_feed` ON `group_feed`.`feed_id` = `feed`.`feed_id`
LEFT JOIN `group` ON `group`.`group_id` = `group_feed`.`group_id`
WHERE
	`auto_send` = 0
AND `feed`.`is_delete` = 0
GROUP BY
	`feed`.`feed_id`
ORDER BY
	`feed`.`gmt_create` DESC
LIMIT 50

下图执行计划分析
$D8V5M2A~_F`@L@WDIJ51.png

如下是后台分页访问情况,一页50条数据
G5$GLP7POE1YWB3GIV1WRS.png

其中 feedgroup_feedgroup 三张表索引情况

CREATE TABLE `feed` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `feed_id` varchar(20) NOT NULL DEFAULT '' COMMENT '动态 id',
  `uuid` varchar(32) NOT NULL DEFAULT '',
  `source` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0.澜渟 1.澜渟医生',
  `type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '类型(0:文字、1:图片、2:视频)',
  `auto_send` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否自动发送 0 否 1 是',
  `text` varchar(1000) NOT NULL DEFAULT '',
  `pic` text NOT NULL,
  `video` text NOT NULL,
  `title` varchar(36) NOT NULL DEFAULT '',
  `cover` varchar(256) NOT NULL DEFAULT '',
  `introduction` varchar(1000) NOT NULL DEFAULT '',
  `collect_total` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '收藏数量',
  `comment_total` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '评论数量',
  `like_total` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '点赞数量',
  `weight` tinyint(4) unsigned NOT NULL COMMENT '推荐权重',
  `is_recommend` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否推荐',
  `recommend_app` tinyint(2) NOT NULL DEFAULT '-1' COMMENT '推荐平台 0. 澜渟 1.澜渟医生 2.全平台',
  `recommend_time` int(10) unsigned NOT NULL DEFAULT '0',
  `is_public` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否发布',
  `is_delete` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除',
  `pv` int(11) unsigned NOT NULL DEFAULT '0',
  `gmt_create` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `feed_id` (`feed_id`),
  KEY `uuid` (`uuid`),
  KEY `type` (`type`),
  KEY `gmt_create` (`gmt_create`)
) ENGINE=InnoDB AUTO_INCREMENT=20980 DEFAULT CHARSET=utf8mb4 COMMENT='动态表';

CREATE TABLE `group_feed` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` varchar(20) NOT NULL DEFAULT '' COMMENT '圈子 id',
  `feed_id` varchar(20) NOT NULL DEFAULT '' COMMENT '动态 id',
  `gmt_create` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `group_id` (`group_id`),
  KEY `feed_id` (`feed_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4404 DEFAULT CHARSET=utf8mb4 COMMENT='圈子动态关联表';

CREATE TABLE `group` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` varchar(20) NOT NULL DEFAULT '' COMMENT '圈子 id',
  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题',
  `cover` varchar(256) NOT NULL DEFAULT '' COMMENT '封面',
  `abstract` varchar(150) NOT NULL DEFAULT '' COMMENT '简介',
  `is_public` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否开启审核 0. 否 1.是',
  `is_release` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '是否发布:0 - 未发布、1 - 已发布',
  `sort` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
  `follow_total` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '关注数',
  `feed_total` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '动态数',
  `app` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'APP(0:澜渟、1:澜渟医生、2:同时)',
  `gmt_create` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `group_id` (`group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8mb4 COMMENT='圈子表';
  • 回答于 2020-02-11 12:26 举报
    GROUP BY `feed`.`feed_id`
    
    UNIQUE KEY `feed_id` (`feed_id`)
    

    这个是不是全表扫描的罪魁祸首??

    6 条回复
    回复于 2020-02-11 13:29 回复

    没懂,这不是唯一索引么,有索引应该会执行,我的理解

    回复于 2020-02-11 14:40 回复

    @刘冲💯 GROUP BY一般去重嘛,去重唯一索引就等于全表扫描了,因为是唯一的嘛。

    回复于 2020-02-12 09:18 回复

    哦哦,这样,我的这个sql如何优化,不用group by 去重 ,就会出现多个相同记录

    回复于 2020-02-12 14:47 回复

    @刘冲💯 嗯?唯一id会有多条记录吗,我看看哪纰漏了。我把sql拷过去看看

    回复于 2020-02-12 15:16 回复

    @刘冲💯 这样,你试试ALTER TABLE feed ADD INDEX (auto_send, is_delete);然后再EXPLAIN看看是不是走索引了。我现在试了下走了索引。

    回复于 2020-02-12 17:57 回复

    谢谢大佬,已经解决了,使用yii2的内部框架机制

  • 回答于 2020-02-12 14:10 举报

    能用 inner join 就用inser join where条件能放 on里就放on 里

您需要登录后才可以回答。登录 | 立即注册
刘冲💯
总监

刘冲💯

注册时间:2017-10-16
最后登录:2021-04-01
在线时长:2小时33分
  • 粉丝1
  • 金钱2470
  • 威望0
  • 积分2490

热门问题