今天洗数据,需要收集表里order与创建时间(月份)的对应关系,一个order可能对应多个时间。
由于表里数据超过300w,且月份需要通过函数(DATE_FORMAT(c_time, '%Y-%m'))获得,不能利用到时间的索引。如果通过以下语句获得,会超时:
SELECT
DATE_FORMAT( c_time, '%Y-%m' ) AS c_time,
`order`
FROM
table_name
GROUP BY `order`,DATE_FORMAT( c_time, '%Y-%m' )
计划先统计出所有的order,然后每200条order执行一次查询
SELECT
DATE_FORMAT(c_time, '%Y-%m') as c_time,
`order`
FROM ${tableName}
WHERE `order` in (order1...ordern)
GROUP BY DATE_FORMAT(c_time, '%Y-%m')
很慢。。
优化:通过union all拼接
SELECT
DATE_FORMAT(c_time, '%Y-%m') as c_time,
`order`
FROM ${tableName}
WHERE `order` = #{order1}
GROUP BY DATE_FORMAT(c_time, '%Y-%m')
union all
SELECT
DATE_FORMAT(c_time, '%Y-%m') as c_time,
`order`
FROM ${tableName}
WHERE `order` = #{order2}
GROUP BY DATE_FORMAT(c_time, '%Y-%m')
...
union all
SELECT
DATE_FORMAT(c_time, '%Y-%m') as c_time,
`order`
FROM ${tableName}
WHERE `order` = #{ordern}
GROUP BY DATE_FORMAT(c_time, '%Y-%m')
依然很慢。
继续优化:查询order时,根据ASC排序。每查询200条时,拿第一个元素的order作为start、第100个元素的order作为end
SELECT
DATE_FORMAT(c_time '%Y-%m') as c_time,
`order`
FROM ${tableName}
WHERE
`order` >= #{startOrder}
AND `order` <= #{endOrder}
GROUP BY DATE_FORMAT(c_time, '%Y-%m')
优化后3s以内