inner join 下 order by 排序不走索引

2020-02-07 12:03:19 +08:00
 OysterQAQ

sql 如下:

select i.* from (select * from illusts order by artist_id,type,create_date)  i  join (select artist_id from user_artist_followed where user_id=53)u using(artist_id) where type='illust' order by create_date desc ;

illust 表下建了个索引(artist_id,type,create_date),user_artist_followed 表建了索引(user_id,artist_id)

查询计划显示似乎先进行了 filesort 之后才走了索引

想请问一下,是否有优化方法,消除 filesort 和临时表

create table

-- auto-generated definition
create table illusts
(
    illust_id       bigint auto_increment comment '主键 id'
        primary key,
    title           varchar(1023)                         not null comment '标题',
    type            varchar(20)                           not null comment '1:ugoira、2:manga、3:illust',
    caption         text      default ''                  not null comment '附言',
    `restrict`      tinyint                               not null comment '限制',
    artist          text                                  not null comment '画师 Json',
    tools           varchar(255)                          not null comment '作画作画工具',
    tags            text                                  null comment '标签 json',
    create_date     datetime                              not null comment '创建时间',
    page_count      int       default 0                   not null comment '页数',
    width           int                                   not null comment '宽度',
    height          int                                   not null comment '高度',
    sanity_level    tinyint                               not null comment '情色级别',
    x_restrict      tinyint                               not null comment '十八禁限制',
    total_bookmarks int                                   not null comment '收藏数',
    total_view      int                                   not null comment '查看数',
    image_urls      longtext  default ''                  not null comment '图片链接',
    artist_id       int                                   not null comment '画师 id',
    update_time     timestamp default current_timestamp() not null on update current_timestamp() comment '更新时间'
)
    comment '插画表' charset = utf8mb4;

create index artist_id_type_create_date_index
    on illusts (artist_id, type, create_date);

create index update_time_total_bookmarks_index
    on illusts (update_time, total_bookmarks);


-- auto-generated definition
create table user_artist_followed
(
    id          int auto_increment
        primary key,
    user_id     int      null comment '用户 id',
    artist_id   bigint   null comment '画师 id',
    create_date datetime null
);

create index user_id_artist_id_create_date
    on user_artist_followed (user_id, artist_id, create_date);


3002 次点击
所在节点    问与答
30 条回复
kifile
2020-02-10 12:49:08 +08:00
恩,刚才的语句,实际 explain 了一下,由于子查询被认为是关联查询,所以其实并没能成功命中 artist_type 的索引,分阶段执行,先获取 artist_id ,再和 type 联合查询就都命中索引了
kifile
2020-02-10 12:52:49 +08:00
set @t=(select group_concat(artist_id) FROM user_artist_followed where user_id=53);
explain select * from illusts where type='illust' and artist_id in (@t);

这样写,中间态没有数据传输,同时也可以命中索引
OysterQAQ
2020-02-10 13:28:45 +08:00
@kifile 感谢,确实可行,但是没有测试上千数据,不知道这样做最终会在多大数据量发生性能下跌
kifile
2020-02-10 13:36:31 +08:00
之后的优化其实就是基于业务场景了,之前看过微博他们好像是大 V 用户的内容信息和非 V 用户的内容信息分开存储,代码逻辑处理两块的内容合并,以优化业务场景
xzc19970719
2020-02-10 14:02:43 +08:00
order by 无过滤 不索引
select * from illusts order by artist_id,type,create_date 你这句还是走的 Using filesort
OysterQAQ
2020-02-10 14:08:57 +08:00
@xzc19970719 有认真看问题吗,,,
OysterQAQ
2020-02-10 14:18:06 +08:00
@xzc19970719 抱歉是我看错了
xzc19970719
2020-02-10 14:25:08 +08:00
@OysterQAQ。。我也是个初学菜鸡。。只想到了 17 楼的办法 但是 mysql5.5 以下 in 不走索引 create_date DESC 的话应该建倒序索引
OysterQAQ
2020-02-10 14:33:23 +08:00
@kifile 老歌 这样查 貌似是用 artist_id 先排序了
OysterQAQ
2020-02-10 14:38:24 +08:00
好像我的需求没办法用索引来排序

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/642744

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX