MySql select - group By 很不爽?

Posted

技术标签:

【中文标题】MySql select - group By 很不爽?【英文标题】:MySql select - groupBy very upset? 【发布时间】:2017-11-07 12:30:55 【问题描述】:

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

我有大约 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 列。我认为问题是因为 select 'touches' ~70% rows and AFTER that is groupBy 它将返回 ~200-400 结果。

当然,我有最常用的列索引。 (MIN()、groupBy 和 order 的列也被索引)

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

会有助于减少列数吗?假设有 60 列?


更新

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

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

有什么想法可以得到可接受的响应时间吗?我们的目标是约 100 毫秒(仍然很多但可以接受)。

来自分析器:

从 0.000101 开始 检查权限 0.000007 打开表 0.000013 初始化 0.000046 系统锁 0.000011 优化 0.000016 统计 0.000096 准备 0.000020 创建 tmp 表 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

【问题讨论】:

我有点不清楚。你能展示一下预期的结果和你得到的实际结果吗? 肯定会有助于修复您的数据库模型 表中的 160 列不仅“很多”而且是不可接受的。让你的团队和你的经理们一起思考并接受这个必须解决的问题。问题只会越来越大。这是我的拙见。祝你好运。 如果同一个hotelId有不同的departureDate,则无效。期望从该查询中获得对 departureDate 有用的信息是错误的 int(11)int(5) 完全相同。 该查询的最佳索引是locality 【参考方案1】:

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

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

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

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

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

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

哦,PRIMARY KEY 是什么?这可能很重要。

【讨论】:

以上是关于MySql select - group By 很不爽?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:是不是可以将 GROUP-BY 的结果加入到两个 SELECT 中?

MYSQL SELECT 与 GROUP。想要限制 GROUP BY 中返回元素的数量

MySQL 错误:SELECT 列表不在 GROUP BY 子句中

mysql group by问题

MySQL 实体框架 Group 和 Select By Date

MySql Group by 与 Pivot