按结果优化查询顺序到使用filesort;

fxu*_*ser 2 mysql sql indexing filesort

查询:

    SELECT
        r.reply_id,
        r.msg_id,
        r.uid,
        r.body,
        r.date,
        u.username as username,
        u.profile_picture as profile_picture
    FROM
        pm_replies as r
        LEFT JOIN users as u
            ON u.uid = r.uid
    WHERE
        r.msg_id = '784351921943772258'

    ORDER BY r.date DESC
Run Code Online (Sandbox Code Playgroud)

我尝试了所有可以想到的索引组合,在谷歌搜索我最好能索引这个,但没有任何效果.

此查询在500个返回的项目上获取0,33计数 ...


说明:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  r   ALL     index1  NULL    NULL    NULL    540     Using where; Using filesort
1   SIMPLE  u   eq_ref  uid     uid     8   site.r.uid  1   
Run Code Online (Sandbox Code Playgroud)

SHOW CREATE pm_replies

CREATE TABLE `pm_replies` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `reply_id` bigint(20) NOT NULL,
 `msg_id` bigint(20) NOT NULL,
 `uid` bigint(20) NOT NULL,
 `body` text COLLATE utf8_unicode_ci NOT NULL,
 `date` datetime NOT NULL,
 PRIMARY KEY (`id`),
 KEY `index1` (`msg_id`,`date`,`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=541 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Run Code Online (Sandbox Code Playgroud)

SHOW创建用户

CREATE TABLE `users` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `uid` bigint(20) NOT NULL,
 `username` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
 `email` text CHARACTER SET latin1 NOT NULL,
 `password` text CHARACTER SET latin1 NOT NULL,
 `profile_picture` text COLLATE utf8_unicode_ci NOT NULL,
 `date_registered` datetime NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `uid` (`uid`),
 UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM AUTO_INCREMENT=2004 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Run Code Online (Sandbox Code Playgroud)

Mat*_*lie 5

对于查询原样,最好的索引似乎是......

pm_replies: (msg_id, date, uid)
users:      (uid)
Run Code Online (Sandbox Code Playgroud)

重要的是pm_replies.您可以使用它来过滤数据(首先是过滤列)然后订购数据(订单列是第二个).

如果您删除了过滤器,则会有所不同.然后你只想要(date, uid)作为你的索引.

索引中的最后一个字段使它对连接更友好,重要的部分实际上是索引users.

还有更多关于这一点的说法,至少在一本书的整个章节,以及如果你想要的几本书.但我希望这会有所帮助.


编辑

不是我建议的索引pm_replies是一个覆盖三个字段的索引,而不仅仅是三个索引.这可确保索引中的所有条目都按这些列进行预排序.这就像在Excel中按三列排序数据一样.

拥有三个单独的索引就像在三个选项卡上拥有Excel数据一样.每个按不同的字段排序.

只有三个字段的一个索引才能得到这种行为......
- 你可以选择一个具有相同msg_id的"一堆"记录
- 整个"束"彼此相邻,没有间隙等
- 整个'束' '按msg_id的日期顺序排序
- 对于具有相同日期的任何行,它们按user_id排序

(同样,user_id部分非常小.)