又是那个百万级数据的数据库表……原本使用分组后查询语句正常运行,现在新的需求要求每个分组的数据显示最新一条,未加Order By之前的查询语句如下,每个分组数据会默认取第一条
SELECT
*
FROM
table1
WHERE
columnX = xxx
GROUP BY column_1
因Order By无法使用在Group By之前,使用在Group By之后只能实现分组后的数据排序,不符合需求,故需要套用子查询,改为
SELECT * FROM (
SELECT
*
FROM
table1
WHERE
columnX = xxx
ORDER BY create_time DESC)
GROUP BY column_1
然而,Order By并未生效!Group By 比Order By先执行,Order By不会对Group By内部进行排序,如果Group By后只有一条记录,那么Order By将无效。
的写法,在Order By之后加入LIMIT,鉴于是百万级别数据,直接LIMIT 10000000一千万,然后生效确实生效了,但是相关博客都没有考虑过这个问题,查询时间直接起飞了,本身百万数据在条件语句查询之后返回时间就在2-3秒左右,一个Limit下去,查询时间直接奔着20秒去了……
SELECT * FROM (
SELECT
*
FROM
table1
WHERE
columnX = xxx
ORDER BY create_time DESC LIMIT 10000000)
GROUP BY column_1
针对这种情况,只有将sql改为(针对百万数据,查询速度约达到5-6秒):
SELECT
* , MAX(create_time)
FROM
table1
WHERE
columnX = xxx
GROUP BY column_1
结果集中可以看到MAX(create_time)和create_time的区别,但是这种情况下,虽然返回了最新一条数据的时间,但是数据本身对应的仍是第一条而不是最新一条,只能选择性显示不变的字段,暂时没有更好的办法。
经研讨,此处最好的解决办法依然是分表,参照table1的结构做一个最新数据表table2出来,插入数据时同时插入table1和table2,只不过table1存储全量数据,table2存储最新数据,即,table2删除现有的column_1下数据再插入新的一条,这样保证每个column_1只对应一条最新数据。查询将分为针对table2的全量查询,和针对table1具体column_1的查询。这样在插入每条数据的时候多了一个删除和插入的操作,但是极大地提高了查询的性能。