0

私は、mysql データベースを介して実行し、ケースで特定の「テスト」を実行するスクリプトを持っています。簡素化されたデータベースには、個人が行った旅行を表すレコードが含まれています。各レコードは 1 回の旅行です。でも往復だけ使いたい。そのため、データベースを検索して、2 つの旅行を互いに照合する必要があります。特定の場所への旅行と特定の場所からの旅行。

スクリプトは正常に動作しています。問題は、データベースに 600.000 を超えるケースが含まれていることです。可能であれば、これを避けるべきであることはわかっています。ただし、このスクリプトの目的と、後でデータベース レコードを使用するためには、すべてがまとまっていなければなりません。

MAMP を使用して iMac で実行する場合、スクリプトの実行には現在数時間かかります。もちろん、大量のメモリなどを使用できることを確認しました。

私の質問は、どうすればスピードアップできるかということです.これを行うための最良のアプローチは何ですか?

これが私が今持っているスクリプトです:

$table          = $_GET['table'];                  
$output = '';                  
//Select all cases that has not been marked as invalid in previous test         
$query = "SELECT persid, ritid, vertpc, aankpc, jaar, maand, dag FROM MON.$table WHERE reasonInvalid != '1' OR reasonInvalid IS NULL";         
$result = mysql_query($query)or die($output .= mysql_error());                    
$totalCountValid = '';         
$totalCountInvalid = '';         
$totalCount = '';                  
//For each record:         
while($row = mysql_fetch_array($result)){                 
    $totalCount += 1;                 
    //Do another query, get all the rows for this persons ID and that share postal codes. Postal codes revert between the two trips                 
   $persid                 = $row['persid'];                 
   $ritid                  = $row['ritid'];                 
   $pcD                    = $row['vertpc'];                 
   $pcA                    = $row['aankpc'];                 
   $jaar                   = $row['jaar'];                 
   $maand                  = $row['maand'];                 
   $dag                    = $row['dag'];         
   $thecountquery  = "SELECT * FROM MON.$table WHERE persid=$persid AND vertpc=$pcA AND aankpc=$pcD AND jaar = $jaar AND maand = $maand AND dag = $dag";                  
   $thecount               = mysql_num_rows(mysql_query($thecountquery));                 
   if($thecount >= 1){                         
      //No worries, this person ID has multiple trips attached                            
      $totalCountValid += 1;                 
   }else{                         
      //Ow my, the case is invalid!                         
     $totalCountInvalid += 1;                         
     //Call the markInvalid from functions.php                          
     $totalCountValid += 1;                          
     markInvalid($table, '2', 'ritid', $ritid);                 
   }         
}                  
//Echo the result         
$output .= 'Total cases: '.$totalCount.'<br>Valid: '.$totalCountValid.'<br>Invalid: '.$totalCountInvalid;                  echo $output; 
4

1 に答える 1

2

あなたの基本的な問題は、あなたが次のことをしていることです。

1) 無効としてマークされていないすべてのケースを取得します。
2) ステップ 1) で取得したケースをループします。

簡単にできることは、1) と 2) で記述されたクエリを 1 つのクエリに結合し、データをループすることです。これにより、物事が少しスピードアップします。

また、次のヒントにも注意してください。

1)すべての列を選択することは、まったく良いことではありません。データがネットワークを通過するには、十分な時間がかかります。ワイルドカードを本当に必要なすべての列に置き換えることをお勧めします。

SELECT * <ALL_COlumns>

2) インデックスを使用する - 控えめに、効率的かつ適切に。それらをいつ使用し、いつ使用しないかを理解してください。

3) 可能であればビューを使用します。
4) MySQLslow query logが、どのクエリを処理して最適化する必要があるかを理解できるようにします。

log_slow_queries  = /var/log/mysql/mysql-slow.log
long_query_time  = 1
log-queries-not-using-indexes 

5) 正しい MySQL フィールド タイプとストレージ エンジンを使用します (非常に重要)
6) EXPLAIN を使用してクエリを分析します。 、チェックする必要がある行の数、およびファイルの並べ替え、一時テーブル、および回避したいその他の厄介なことを行う必要があるかどうか。

幸運を。

于 2012-07-28T09:46:51.380 に答える