我有以下疑问:
select count(*) as aggregate from users where date(created_at) < '2024-04-01';
它返回2337355
,这是一个正确的数字.但执行时间超过1.5
秒.知道如何才能使其更优化、更快吗?
注意到我在users(created_at, type)
上有一个idex.
还try 像where created_at < '2024-04-01';
一样删除date()
功能,但仍然很慢.
我有以下疑问:
select count(*) as aggregate from users where date(created_at) < '2024-04-01';
它返回2337355
,这是一个正确的数字.但执行时间超过1.5
秒.知道如何才能使其更优化、更快吗?
注意到我在users(created_at, type)
上有一个idex.
还try 像where created_at < '2024-04-01';
一样删除date()
功能,但仍然很慢.
COUNT()
个查询往往比人们想象的要昂贵.它们的成本与判断数百万行的任何其他查询一样高.
有些人认为,因为COUNT()
返回单个整值结果,所以这个结果相当小,因此查询必须比获取所有数据更快.但事情的运作方式并非如此.
查询的成本大致与判断的行数成正比,而不是结果的大小.
为了计算行,InnoDB必须为每一行examine行,因为MMCC.使用索引有助于减少判断的行的数量,但这仍然需要判断数百万行.
因此,它的性能成本与出于其他目的读取相同数量的行的查询几乎相同.当然,将一个整数传递回客户端比返回数百万行更快,但网络传输速度并不是这里的瓶颈.
使您的查询更快的变通方法包括:
缓存代价高昂的查询的结果,这样您就不必经常运行它.
缓存部分结果,例如每日计数,然后对您感兴趣的某些日期范围的这些计数进行总和.这涉及判断更少的行(例如每天一行),因此应该快得多.
获得更快的服务器硬件和更多的缓冲池RAM.它可能仍然需要判断数百万行,但如果它在更强大的服务器上做得更快,它就会更快地为您提供结果.它不太可能大幅提高性能,但至少可以为您带来一定的百分比改进.