2

良い一日、私は私がたくさん苦労している質問があります、誰かがこれに対する賢い解決策をすでに見つけたことを願っています(私はMySQLを使用しています)。

私はこのようなテーブルを持っています:

Table `log`
----------
id
inserted
message
user_id

私の目標は、ユーザーの最後に挿入されたレコードを選択し、これを高速化することです。ログテーブルは巨大(約90万レコード)なので、最初のアプローチは次のとおりです。

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN 
(
 SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
)

しかし、すべての行のサブクエリを計算しているようです(EXPLAINはDEPENDENT QUERYを示しています)。このクエリを2つに分割すると、次のようになります。

SELECT MAX(`id`) FROM `log` GROUP BY `user_id`

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN (....ids from first query...)

実行してもかまいません。これは1つのクエリで達成できますか?

4

4 に答える 4

4

どうですか

SELECT user_id, max(id) FROM `log` GROUP BY user_id

これにより、ログテーブル内のすべてのユーザーの最大IDがすべて1つのクエリで取得されます。

于 2010-02-09T21:13:00.357 に答える
1

特定のユーザーのログを常に探している場合は、ログファイルをuser_idでパーティション化すると、処理速度が大幅に向上します。テーブルがユーザーによってパーティション化され、IDによってインデックスが付けられている場合、クエリは非常に高速に実行されます。

編集:ドミニクのクエリを参照してください

于 2010-02-09T21:13:48.240 に答える
1

group by を使用してグループごとの最大値を取得することに加えて、テーブルから特定の行の追加フィールドを取得するために、おそらくそれを非相関サブクエリにしたいと思うでしょう。

SELECT
  la.user_id,la.message
FROM
  `log` as la
INNER JOIN
  (
    SELECT
      user_id, MAX(id) AS maxid
    FROM
      `log`
    GROUP BY
      user_id
    ) as lb
ON
  la.id = lb.maxid

インデックスがある場合、これは最適/最速で機能します

KEY `foo` (`user_id`,`id`)

しかし、そのキーがなくても、パフォーマンスは下降しています。

于 2010-02-09T21:55:56.583 に答える
0

さらに、user_idにインデックスがあることを確認します。

編集:一般化

于 2010-02-09T21:15:52.307 に答える