当我不能使用索引来满足行的排序时,如何使具有小 LIMIT(即一次 20 行)的 ORDER BY 子句快速返回?
假设我想从表“节点”(下面简化)中检索一定数量的标题。顺便说一句,我正在使用 MySQL。
node_ID INT(11) NOT NULL auto_increment,
node_title VARCHAR(127) NOT NULL,
node_lastupdated INT(11) NOT NULL,
node_created INT(11) NOT NULL
但我需要将返回的行限制为仅特定用户有权访问的行。许多用户可以访问大量节点。我在一个大查找表中预先计算了这些信息(试图让事情变得更容易),其中主键涵盖两列,并且行的存在意味着用户组可以访问该节点:
viewpermission_nodeID INT(11) NOT NULL,
viewpermission_usergroupID INT(11) NOT NULL
因此,我的查询包含类似
FROM
node
INNER JOIN viewpermission ON
viewpermission_nodeID=node_ID
AND viewpermission_usergroupID IN (<...usergroups of current user...>)
...而且我还使用 GROUP BY 或 DISTINCT 以便即使两个用户的“用户组”都可以访问该节点,一个节点也只会返回一次。
我的问题是,对于按创建或上次更新日期对结果进行排序的 ORDER BY 子句似乎无法使用索引,因为返回的行取决于另一个 viewpermission 表中的值。
因此 MySQL 需要找到所有符合条件的行,然后自己对它们进行排序。如果特定用户有一百万行,并且我们想查看最新的 100 行或按上次更新排序时的 100-200 行,则数据库需要确定用户可以看到哪些一百万行,排序这整个结果集本身,在它可以返回那 100 行之前,对吧?
有没有什么创造性的方法来解决这个问题?我一直在思考:
- 以某种方式将日期添加到查看权限查找表中,以便我可以建立一个包含日期和权限的索引。我猜这是一种可能。
编辑:简化问题
也许我可以通过这样重写来简化问题:
有什么方法可以重写此查询或为以下内容创建索引,以便可以使用索引进行排序(不仅仅是选择行)?
SELECT nodeid
FROM lookup
WHERE
usergroup IN (2, 3)
GROUP BY
nodeid
(usergroup) 上的索引允许索引满足 WHERE 部分,但 GROUP BY 强制对这些行使用临时表和文件排序。(nodeid) 上的索引对我没有任何作用,因为 WHERE 子句需要一个以用户组作为第一列的索引。(usergroup, nodeid) 上的索引强制使用临时表和文件排序,因为 GROUP BY 不是可以变化的索引的第一列。
有什么解决办法吗?