1

次のようなクエリを発行した場合の MySQL の問題についてはよく知っています。

SELECT `user_log`.`USER_NAME`, MAX(`user_log`.`ACCESS_DATE_TIME`), `user_log`.`COMPUTER_NAME`, `user_log`.`LOCATION`  
    FROM `user_log` 
    GROUP BY `user_log`.`USER_NAME` 
    ORDER BY `user_log`.`ACCESS_DATE_TIME` DESC

ご想像のとおり、これは MAX ACCESS_DATE_TIME に関連付けられた COMPUTER_NAME と LOCATION を返しません。GROUP BY 列で定義されたセットの最初の値 (USER_NAME のすべて) を返します。

したがって、これを回避するために、MAX ... GROUP BY sql をリンクするクエリを作成しようとしています。これは、必要なすべての列を選択するクエリであり、USER_NAME と ACCESS_DATE_TIME は、ユーザーの MAX を取得するセットに分類されます。 ...GROUP ステートメント。

これは私が持っているものです - >

SELECT `user_log`.`USER_NAME`, `user_log`.`ACCESS_DATE_TIME`, `user_log`.`COMPUTER_NAME`, `user_log`.`LOCATION` 
FROM `user_log`.`user_log` 
JOIN (SELECT `user_log`.`USER_NAME`, MAX(`user_log`.`ACCESS_DATE_TIME`) as sub_max 
    FROM `user_log` 
    GROUP BY `USER_NAME` 
    ORDER BY sub_max DESC) as sub
WHERE (`user_log`.`USER_NAME` = sub.`USER_NAME` AND `user_log`.`ACCESS_DATE_TIME` = sub.sub_max)

ただし、それほど高速ではありません....これを行うためのより良い方法はありますか? 誰かが今までに何かを思いついたと確信しています...

4

2 に答える 2

1

代わりに、パフォーマンスを一時テーブルと比較します(テストされていません)。

CREATE TEMPORARY TABLE `user_log_temp` ENGINE=memory
SELECT `user_log`.`USER_NAME`, MAX(`user_log`.`ACCESS_DATE_TIME`) as sub_max 
FROM `user_log` 
GROUP BY `USER_NAME`;

SELECT `user_log`.`USER_NAME`, `user_log`.`ACCESS_DATE_TIME`, `user_log`.`COMPUTER_NAME`, `user_log`.`LOCATION` 
FROM `user_log`.`user_log` 
JOIN `user_log_temp` as sub 
  ON `user_log`.`USER_NAME` = sub.`USER_NAME`
  AND `user_log`.`ACCESS_DATE_TIME` = sub.sub_max;

DROP TABLE `user_log_temp`;
于 2012-09-28T15:44:26.080 に答える
0

これが私が実装したものです->

MAX...GROUP BY リレーションでテーブルを作成するには ->

CREATE TABLE `user_log_max`
   SELECT
     `USER_NAME`, 
      /* Alias this calculated value as ACCESS_DATE_TIME */
      MAX(`ACCESS_DATE_TIME`) AS `ACCESS_DATE_TIME` 
   FROM `user_log`
   GROUP BY `USER_NAME`

すべてのデータを取得するには ->

SELECT DISTINCT `user_log`.`COMPUTER_NAME`, `user_log`.`LOCATION`, `user_log`.`USER_NAME`, `user_log`.`ACCESS_DATE_TIME` 
FROM `user_log`, `user_log_max`
WHERE `user_log_max`.`USER_NAME` = `user_log`.`USER_NAME` AND `user_log_max`.`ACCESS_DATE_TIME ` = `user_log`.`ACCESS_DATE_TIME`

適切なインデックスを追加してください。そうしないと、まだ遅くなります。

時間の経過とともに関連性がなくなるため、必要に応じて、完了時にテーブルをドロップすることもできます ->

DROP TABLE `user_log_max`
于 2012-09-28T16:52:34.570 に答える