查询:
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/