2009-06-08 15 views
6

私は、この問題を抱えている少数のユーザーに代わってこの質問をしています。MySQLのMAX_JOIN_SIZEのエラー

、彼らが使用しているスクリプトが21 IDに到達したら、それは次のエラーを生成します。

The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

私はできるだけこの限り調査し、答えのようなものを発見した:http://dev.mysql.com/doc/refman/5.0/en/set-option.html

問題は彼らが共有ホスティングの上にいるので、MySQL設定を変更してエラーを修正できないということです。

この問題が発生しないようにスクリプトに書き込むことはできますか?

これは、ロードされるモジュールに基づいてデータベースクエリを生成する関数です。 $ sql = 'idとしてid a.idを、アドレスとしてa.addressを選択';

 $query = 'SELECT' 
       . ' name AS module_name' 
       . ', databasename AS module_database' 
       . ', pregmatch AS module_pregmatch' 
       . ', pregmatch2 AS module_pregmatch2' 
       . ', html AS module_html' 
       . ', sqlselect AS database_sqlselect' 
       . ', sqljoin AS database_sqljoin' 
       . ', sqlupdatewithvalue AS database_sqlupdatewithvalue' 
       . ', sqlupdatenovalue AS database_sqlupdatenovalue' 
       . ' FROM #__aqsgmeta_modules' 
       . ' WHERE enabled = 1' 
       . ' ORDER BY id';      
     $db->setQuery($query); 
     $results = $db->loadObjectList(); 
     if (count($results) != 0) { 
      foreach ($results as $result) { 
       $sqlselect .= ', '; 
       $sqlselect .= $result->database_sqlselect; 

       $sqljoin .= ' '; 
       $result->database_sqljoin = preg_replace('/\{DATABASENAME\}/Ui', $result->module_database, $result->database_sqljoin); 
       if (!(preg_match("/" . $result->database_sqljoin . "/Ui", $sqljoin))) 
        $sqljoin .= $result->database_sqljoin; 
      } 
     } 

     if ($use_sh404sef) 
      $sqlselect .= ', g.oldurl AS sefurl'; 
     $sql .= $sqlselect; 
     $sql .= ' FROM #__aqsgmeta_address AS a'; 
     $sql .= $sqljoin; 

     if ($use_sh404sef) 
      $sql .= ' LEFT JOIN #__redirection AS g ON g.newurl = a.address'; 

     $sql .= 
     //. ' WHERE a.id IN (' . $cids . ')' 
     ' WHERE a.id = ' . $id 
     . ' ORDER BY a.address asc,a.id ' 
     ; 
     $db->setQuery($sql); 
     $rows = $db->loadObjectList(); 
+0

クエリが最適化されていること、つまり、より少ない中間結果セットで同じ結果を得る方法がないことは確かです。 – VolkerK

答えて

13

MAX_JOIN_SIZEは、一般的に共有hostingsに使用セーフティキャッチです。

サーバーをハングするような長いクエリを誤って実行させることはありません。

次のコマンドを発行します。

SET OPTION SQL_BIG_SELECTS = 1 

あなたが値の多くを返すために知っているクエリを実行する前に。

4

MAX_JOIN_SIZEは、MySQLがジョインのデカルト積を計算するときにヒットします。実際の予想されるレコードは戻っていません。したがって、大規模なテーブルを別の大規模なテーブルに結合している場合、これは這い上がります。インデックスとビューを使用して、可能なテーブルヒットが実際にそれほど大きい場合には、そのヒットを減らします。

はもっとここを参照してください:MySQL - SQL_BIG_SELECTS