带有where子句和group by的SQL max()函数不能有效地使用索引

Mik*_*ike 6 sql sql-server indexing max

我有一个MYTABLE大约有25列的表,其中两列是USERID (integer)USERDATETIME (dateTime).

我在这两个列上有一个关于此表的索引,USERID后面是第一列USERDATETIME.

我想获得每个USERID的最大USERDATETIME.所以:

select USERID,MAX(USERDATETIME) 
from MYTABLE WHERE USERDATETIME < '2015-10-11'
GROUP BY USERID
Run Code Online (Sandbox Code Playgroud)

我希望优化器能够找到每个唯一的USERID和最大的USERDATETIME,其中搜索次数等于唯一USERIDs 的数量.而且我希望这是合理的.我在myTable中有2000个用户ID和600万行.但是,实际计划显示索引扫描中有600万行.如果我使用USERDATETIME/ 的索引USERID,计划将更改为使用索引搜索,但仍然是600万行.

为什么SQL不会以减少处理行数的方式使用索引?

Lau*_*gil 0

WHERE 子句是使用索引的查询的限制因素。

对于标准 SQL Server 查询,索引用于快速选择记录(该索引允许),以及限制返回的记录(该索引不允许。那么,为什么这个索引不允许快速限制呢?

当查询优化器考虑基于 WHERE 子句的优化时,它会查找以 WHERE 子句中的项目开头的索引,或者可用于有效识别允许(或不允许)的记录的索引位于结果集中。

通过这个索引,服务器首先可以找到所涉及的不同用户ID。然后它会想要限制基于 WHERE 子句考虑的行。然而,为了做到这一点,优化器可能会估计在定位用户 ID 后必须执行相当于完整索引或表扫描的操作。

另一种可能的替代策略是扫描索引,同时识别用户 ID 和日期。这就是优化器选择的。

一种可能的解决方案是除了正在使用的索引之外,还使用不同的索引 - 按日期索引,然后是用户 ID 索引。这将限制为识别用户 ID 最大值而扫描的记录数量,因此速度会更快一些。

请注意,如果不需要 WHERE 子句,您的索引将会很快。但是 where 子句要求优化器考虑 WHERE 子句将所选项目限制为所考虑的最后一行的用例。

此外,日期字段按降序排列的索引也可能更有效。