mysql - 将查询结果优化为使用文件排序;

标签 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

我尝试了我能想到的所有索引组合,在谷歌中搜索了如何最好地对此进行索引,但没有任何效果。

此查询对 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   

显示创建 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

显示创建用户

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

最佳答案

对于查询本身来说,最好的索引似乎是......

pm_replies: (msg_id, date, uid)
users:      (uid)

最重要的是pm_replies。您可以使用它来过滤数据(过滤器列在第一个),然后对数据进行排序(顺序列在第二个)。

如果您删除过滤器,情况会有所不同。那么您只需要 (date, uid) 作为索引。

索引中的最后一个字段只是使其对连接更加友好,重要的部分实际上是用户上的索引。

关于这一点还有很多可以说的,至少一本书中的一整章,如果你愿意的话可以写几本书。但我希望这会有所帮助。


编辑

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

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

只有三个字段中的一个索引才会出现这种行为...
- 您可以选择具有相同 msg_id 的“一堆”记录
- 整个“一堆”彼此相邻,没有间隙等
- 整个“一堆”按该 msg_id 的日期顺序排序
- 对于具有相同日期的任何行,它们按 user_id 排序

(同样,user_id 部分确实非常小。)

关于mysql - 将查询结果优化为使用文件排序;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9734804/

相关文章:

php - 查询 : select between dates and display based on day

sql - 为名称/值对数据创建 SQL 查询

sql - Impala 中的增量整数 ID

MySQL & 嵌套集 : slow JOIN (not using index)

mysql - Rails ActiveRecord 处理一个不是主键的 id 列

MySQL 选择前 10 个最常出现的字段值

mysql - 语法 WHERE 子句

matlab - 在 MATLAB 中获取 0 数组中随机 1 的位置

sql - MySql,任何人都可以建议如何改进我的查询/索引吗?

php - 使用php的Mysql事件错误