【发布时间】: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。
标签: mysql database select optimization group-by