0

メッセージ テーブルとログ テーブルの 2 つのテーブルがあります。

ユーザーに記録され、メッセージ # が渡されたパラメーターより大きいすべての行をメッセージ テーブルに返したいと考えています。

私が持っているものは次のとおりです。

SELECT * FROM message WHERE id IN ( SELECT msg_id AS id FROM msg_log WHERE user_num='1000' AND msg_id >='1660192')

このクエリは何も返さず、エラーも発生せず、単にタイムアウトします... PHP スクリプトまたは phpMyAdmin から実行するかどうかは問題ではありません。実際、phpMyAdmin から実行すると、クエリが実行されていることさえ表示されませんが、別のクエリを実行することはできません。

IN選択を解除すると

SELECT msg_id AS id FROM msg_log WHERE user_num='1000' AND msg_id >='1660192')

これは 0 レコードを返します (当然のことです)。

この問題を解決するにはどうすればよいですか?

4

3 に答える 3

2

これを試して:

SELECT message.* FROM message 
INNER JOIN msg_log 
    ON message.id = msg_log.msg_id
   AND msg_log.user_num = '1000' 
   AND msg_logmsg_id >= '1660192'

INNER JOIN構文は句よりも高速である必要がありますIN
当然、クエリを高速化できます

  • message.id asINDEXまたはPRIMARY_KEY
  • msg_log.id としてINDEX、おそらくmessage.idに関連しているFOREIGN_KEY
于 2012-08-20T19:54:55.197 に答える
0

MySQLの特性により、内部結合はINよりも高速です。MySQLが行うことは、検出したすべての行に対してサブクエリを実行することです。これはデータベースでは異常な動作ですが、文書化されています。

結合すると、この問題が修正されます。ただし、適切な同等の構文には、次のものが必要です。

SELECT m.*
FROM message m join
     (select distinct msg_id
      from msg_log
      WHERE user_num='1000' AND msg_id >='1660192'
     ) ml
     on ml.msg_id = m.id

メッセージごとに複数の行がないようにする場合は、区別することが重要です。

EXISTS句を使用して修正することもできます。

SELECT *
FROM message m
WHERE EXISTS (SELECT 1
              FROM msg_log ml
              WHERE user_num='1000' AND msg_id >='1660192' and m.id = ml.msg_id
             )

結合よりも相関サブクエリを優先する場合。

于 2012-08-20T20:08:22.623 に答える
0

PHPなしでmysqlモニターからこのクエリを実行しようとしましたか? 大きなテーブルがあり、mysql がクエリを実行するために、php スクリプトが許可されているよりも多くの時間を必要とする場合があります。あなたは試すことができます:

1) msg​​_log テーブルの user_num にインデックスを追加すると、クエリが高速化される可能性があります。

2)phpがより長いスクリプトを実行できるように設定php_max_execution_timeします.htaccess

于 2012-08-20T19:53:50.417 に答える