MySql select - group By 很苦恼吗?

标签 mysql database select optimization group-by

也许这个问题太宽泛,但我真的需要这个:

我有大约 80k 行和大约 160 列的表(我知道很多)。不幸的是,我有常规选择,例如:

SELECT hotelName
     , country
     , locality
     , destination
     , foodType
     , hotelStars
     , departureDateFrom
     , departureDateTo
     , MIN(price) 
  FROM table 
 WHERE locality
   IN (
     '1', '2', '3'
   )
   AND visible IS NOT NULL
   AND departureDateFrom >= (?)
   AND departureDateTo <= (?)
   AND foodType = (?)
   AND hotelStars = (?)
   AND country
   IN (
     '1', '2', '3'
   )
 GROUP 
    BY hotelId 
 ORDER 
    BY price ASC

表格中是旅游。因此,您可以拥有 250 条具有相同酒店名称、地点...但价格或出发日期不同的记录。主键是id,在本例中没有出现。 hotelId 是来自另一个系统的 ID,其在该项目中的用途仅用于“获取酒店详细信息”和 groupBy(保证结果中唯一的酒店)

要点是 - 我必须在每个选择中进行 groupBy + MIN() + order

所以主要问题是查询时间较长,每个请求约 250 毫秒。

我的选择平均有 10-15 列。我认为问题是因为选择“触摸”约 70% 行,然后是 groupBy,它将返回约 200-400 个结果。

当然,我已经对最常用的列进行了索引。 (MIN()、groupBy 和 order 的列也被索引)

  • 在这种情况下无法进行缓存。
  • 我无法影响数据结构。
  • 我还有其他选择可以加快速度吗?

减少列数会有帮助吗?比如说 60 列?

<小时/>

更新

  • 表格减少到 65 列
  • 现在删除的所有索引仅是 groupBy 的 hotelId 列上的一个 (BTREE)
  • 优化了一些数据类型,例如 hotelId 上的 int(11) 到 int(5)

我们现在的响应时间是-25%,所以现在我们的响应时间约为 190 毫秒。

有什么想法可以获得可接受的响应时间吗?我们的目标是~100ms(仍然很多,但可以接受)。

来自探查器:

从 0.000101 开始
检查权限0.000007
开表 0.000013
初始化0.000046
系统锁0.000011
优化 0.000016
统计 0.000096
准备0.000020
创建临时表 0.000029
对组 0.000011 进行排序
排序结果0.000006
执行0.000004
发送数据0.176949
创建排序索引 0.000916
结束 0.000009
查询结束0.000011
删除 tmp 表 0.000602
查询结束0.000008
收盘表 0.000012
释放元素 0.000052
清理 0.000033

最佳答案

您提供的数字听起来像是整个表都缓存在 RAM 中。因此,它可能不受 I/O 限制。

无论如何,触及 56K 行都需要时间。

最好的索引可能是这个复合INDEX(col1, col2, col3)。 (请调整“行”和“列”之间的术语。)

GROUP BY col5 ORDER BY col6 必然会创建两个临时表,并对每个表进行排序。

选择列(col2、col3、col6)(显然)不依赖于GROUP BY<时,GROUP BY col5通常是不合适的 列。您将获得这三列的随机值。好吧,也许 col5UNIQUE,因此没有问题。 (如果可以的话,请提供真实姓名,这将有助于我们为您提供帮助。)

我怀疑您所涉及的列有很多种类,否则,我建议“覆盖”INDEX(col1, col2, col3, col4, col5, col6) - 前 3 个列按该顺序排列,其余部分按任意顺序排列。

哦,主键是什么?这可能很重要。

关于MySql select - group By 很苦恼吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44390872/

相关文章:

mysql - 如果我们依赖语句中的索引扫描顺序,两个 InnoDB UPDATE 语句是否可以防止 PK 索引死锁?

ios - 在iCloud仪表板中添加团队成员

javascript - 复选框和选择选项更新总计值

javascript - 使用jQuery Redux隐藏选择列表中的选项

php - 如何计算任何给定 $variables 在 MySql 表的列中出现的次数

MYSQL 使用的 SELECT 语句有不同的列数

MySQL 查询同一天多年来的每日平均值

mysql - 我的 SQL 工作台在 EER 图中创建多对多关系

ios - 无法快速获取我的信息 datatask 3

jquery - 如何使用 JQuery 查找 DOM 选择对象上的选定索引?