我的表总共有2,707,047行。
SELECT * FROM messages WHERE status = 1 AND room_id IN (14, 16, 19, 21, 23, 24, 31, 32, 33, 36, 37, 39, 40, 45, 46, 54, 55, 56, 58, 59, 61, 65, 66, 70, 71, 73, 76, 78, 84, 85, 86, 94, 95, 96, 97, 98, 101, 106, 113, 114, 117, 118, 120, 121, 122, 131, 134, 136, 138, 139, 140, 141, 144, 145, 146, 147, 148, 149, 150, 153, 154, 155, 156, 157, 158, 159, 160, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 208, 209, 210, 212, 213, 214, 215, 217, 218) ORDER BY post_date DESC LIMIT 0, 1
需要0.0059秒
SELECT * FROM messages WHERE status = 1 AND room_id IN (40) ORDER BY post_date DESC LIMIT 0, 1
需要0.0078秒
SELECT * FROM messages WHERE status = 1 AND room_id IN (39) ORDER BY post_date DESC LIMIT 0, 1
需要0.0510秒
但为什么?
答案 0 :(得分:2)
第二次和第三次查询的最佳索引是:messages(status, room_id, post_date)
。有了这个索引,我希望性能几乎相同。
如果没有索引,查询将获得与where
子句匹配的行,然后对它们进行排序。好吧,如果39号房间的行数比40号房间多,那么排序需要更长的时间。
您的问题中未包含其他有用信息。 。 。例如查询的“解释”计划或现有索引。但是,有充分的理由将值从39改为40会影响结果。
编辑:
第一个因为偶然事件而很快。由于in
条件,MySQL决定status, room_id, post_date
上的索引不是最优的。相反,它按降序读取日期的索引,并且恰好找到一个非常快速匹配where
条件的行。
第二和第三个性能差异有点神秘。他们建议MySQL正在进行索引扫描,以便在索引的匹配部分中找到最后一个发布日期。但是,考虑到数据不是很大,我不希望性能因数为7。
这些性能特征是否一致?在冷缓存环境中保持差异吗?
答案 1 :(得分:0)
因为您正在使用LIMIT 0, 1
,所以较长的IN
子句通常会更快地评估(没有索引),因为它可以在找到任何 room_id
s,而其他两个查询必须找到指定的 exact room_id
。
我认为第二个和第三个查询之间的差异可能只取决于扫描中特定room_id
发生的位置。