5

ユーザーがゲームのプレイに費やした合計時間を見つけるために、単純な MySQL クエリを実行しています。

SELECT userId, SUM(time) AS totalGameTime
                    FROM game_attempts
                    WHERE userId = 19599

EXPLAIN は以下を示します。

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra
1  SIMPLE  game_attempts  ref  userId_gameId  userId_gameId  4  const  26880  

プロファイラーは、ほとんどの時間が「データの送信」に費やされていることを示しています。

Sending data    1.786524

なぜこのような単純なクエリを完了するのに時間がかかるのでしょうか? ボトルネックを探す場所

アップデート。時刻は INT(11) フィールドであり、変換は含まれません。

アップデート。考えられる解決策は、(userId, time) インデックスを導入することです。これは、データの一部をインデックス ツリーに移動することで問題を解決します。しかし、なぜ 30000 個の整数を合計するのに時間がかかるのかという大きな問題は解決しません。

この質問には簡単な答えはありません。インデックスは正しく、時間のかかる変換は必要ありません。それは単に DB エンジンのチューニングに関するものです。30000 レコードを見つけてデータを取得するのになぜそんなに時間がかかるのでしょうか?

重要なのは、InnoDB エンジンを使用したテーブルで、約 200 万のレコードが含まれていることです。

4

6 に答える 6

1

多数の行をクライアントに返していることを示唆しています。追加できますか

GROUP BY userId

1行だけ返すようにするには?

于 2013-07-30T09:37:48.170 に答える
0

userId にインデックスを作成します。これにより、失敗した userId を持つレコードへのアクセスが制限されます。

于 2013-07-30T09:18:25.107 に答える
0

他のほぼすべての DBMS では、クエリの選択部分に集計関数と GROUP BY 句の一部ではないフィールドが含まれているため、ステートメントは無効な SQL と見なされます。実際、GROUP BY 句はありません。 .

オラクルの例はあなたに教えてくれます:

ORA-00937: 単一グループのグループ関数ではありません

MSSQL でも同様の結果が得られます。MySQL がここで行うことは、SUM の方法を必要以上に頻繁に計算することだと思います。

次のクエリは、より SQL 標準に準拠しており、高速になります。

SELECT userId, SUM(time) AS totalGameTime
  FROM game_attempts
 WHERE userId = 19599
GROUP BY userId;
于 2013-07-30T09:46:25.107 に答える
0

「時間」列の精度が高すぎませんか? 合計するとどうなるか

SEC_TO_TIME(SUM(TIME_TO_SEC(time)))

代わりは?

于 2013-07-30T10:36:02.683 に答える
0

わかりました、これを anwser として書き留めますので、このエラーを再度行うことはできません

MySQL 5.0.23以降は設定できます

ONLY_FULL_GROUP_BY by SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY ';

サーバーを正しく構成してください

mysql> SELECT name, MAX(age) FROM t;
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
with no GROUP columns is illegal if there is no GROUP BY clause

ソース ( http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_only_full_group_by )

于 2013-08-14T22:09:48.607 に答える