带有内部子查询的 Mysql 查询以及 where、order、group 不使用索引

Posted

技术标签:

【中文标题】带有内部子查询的 Mysql 查询以及 where、order、group 不使用索引【英文标题】:Mysql query with inner subquery and where,order,group not use indexes 【发布时间】:2015-08-10 13:06:41 【问题描述】:

全部。 我有 2 个 mysql 表类型 myisam

CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `users_ratings` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `created_date` varchar(255) DEFAULT NULL,
  `user_id` mediumint(9) DEFAULT NULL,
  `rating1` mediumint(9) DEFAULT NULL,
  `rating2` mediumint(9) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

转储可以下载here

我希望所有用户按 rating2 选择和排序列表, rating2 必须 > 1000

SELECT * FROM users as u 
INNER JOIN (SELECT rating2, user_id,MAX(created_date) as maxdate FROM `users_ratings` GROUP BY user_id) as x ON x.user_id = u.id 
INNER JOIN users_ratings as ur ON(ur.created_date = x.maxdate and ur.user_id = u.id) 
WHERE x.rating2 > 1000 
ORDER by ur.rating2

如果没有这样的索引,查询会执行 9 秒。

所有可能的代码,我认为可以将请求时间减少到 1-2 秒。

帮助放置索引的权利

【问题讨论】:

一般来说,在聚合查询中,如果您选择一个未聚合的列,那么您还需要将它包含在您的 GROUP BY 子句中。 MySQL 可以原谅这一遗漏(其他 RDBMS 不会),但可能会导致不可预测和令人困惑的结果。 sqlfiddle 比从谷歌驱动器下载更好的设置供人们查看 您的问题不清楚。例如,created_date 与什么有关?最高评分就够了吗? 我想获得最新的(最大(created_date))rating1 和 rating2 的用户。数据库保持用户评分的动态变化。 @Drew Пока что не имею опыта рыботы с sqlfiddle, но в будущем научусь, спасибо! 【参考方案1】:

我怀疑您想要以下查询。假设您这样做了,并且性能仍然是一个问题,请提供相同的解释...

(假设user_id,[rating2,]created_date 上的唯一键,实际上并没有指定)

SELECT u.*
     , x.*
  FROM users u 
  JOIN users_ratings x
    ON x.user_id = u.id
  JOIN 
     ( SELECT user_id
            , MAX(created_date) maxdate 
         FROM users_ratings
        WHERE rating2 > 1000
        GROUP 
           BY user_id
     ) y 
    ON y.user_id = x.user_id 
   AND y.maxdate = x.created_date
 ORDER 
    BY x.rating2;

【讨论】:

我尝试按照您的建议制作唯一索引,基于测试的查询结果非常满意。谢谢。我会明白我的错误是什么。 Screenshot 实时性能Screenshot 增加了表 users_ratings(186к) 和 users(76k) 中的条目数 此查询执行 700 毫秒。仍在寻找解决方案。预计用户记录约200万条

以上是关于带有内部子查询的 Mysql 查询以及 where、order、group 不使用索引的主要内容,如果未能解决你的问题,请参考以下文章

mysql查询语句 和 多表关联查询 以及 子查询

从选项(来自 rds - mysql)创建动态框架,提供带有 where 子句的自定义查询

mysql 将子查询排除在连接之外

mysql_数据查询_嵌套查询

如何编写带有子查询的 Django 查询作为 WHERE 子句的一部分?

MySQL的SQL语句 - 数据操作语句(13)- 子查询(12)