行の順序を満たすためにインデックスを使用できない場合、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を使用して、ユーザーの「ユーザーグループ」の2つが両方ともそのノードにアクセスできる場合でも、ノードが1回だけ返されるようにします。
私の問題は、返される行が他のviewpermissionテーブルの値に依存するため、作成日または最終更新日で結果を並べ替えるORDERBY句がインデックスを使用する方法がないように見えることです。
したがって、MySQLは、条件に一致するすべての行を検索してから、それらをすべて自分で並べ替える必要があります。特定のユーザーに100万行があり、たとえば、最新の100行または最後の更新順に並べられた100〜200行を表示する場合、DBは、ユーザーが表示できる100万行を把握して並べ替える必要があります。この100行を返す前に、この結果セット全体がそれ自体になりますよね?
これを回避するための創造的な方法はありますか?私は次のように考えてきました:
- どういうわけか、ビューパーミッションルックアップテーブルに日付を追加して、日付とパーミッションを含むインデックスを作成できるようにします。それは私が推測する可能性です。
編集:簡略化された質問
おそらく、次のように書き直すことで、質問を単純化できます。
このクエリを書き直したり、次のインデックスを作成して、インデックスを使用して順序付けを行うことができるようにする方法はありますか(行を選択するだけではありません)?
SELECT nodeid
FROM lookup
WHERE
usergroup IN (2, 3)
GROUP BY
nodeid
(usergroup)のインデックスを使用すると、WHERE部分をインデックスで満たすことができますが、GROUP BYは、これらの行に一時テーブルとファイルソートを強制します。WHERE句には、最初の列としてusergroupを持つインデックスが必要なため、(nodeid)のインデックスは私には何もしません。(usergroup、nodeid)のインデックスは、GROUP BYが変更される可能性のあるインデックスの最初の列ではないため、一時テーブルとファイルソートを強制します。
解決策はありますか?