0

最近、当社の製品の郵便番号の位置 (緯度と経度の座標) が、「短い」郵便番号 (「ABD 1PT」ではなく「AB10」など) に対して正しくないことに気付きました。

郵便番号データベース/テーブルは、Google マップ上にピンを生成するために使用されます。短い郵便番号を完全な郵便番号を含むテーブルにマージしたある時点で、一部 (2200 前後) に経度と緯度が誤って入力されていたことがわかりました。間違った方法で。

明らかに、これは簡単な修正なので、間違った値を処理する (基本的にそれらを交換する) 小さなスクリプトを作成することにしました。

ここに私が持っているものがあります:

<cfscript>

  /** Fetch the wrong postcodes data **/
  db  = "postcodes";
  sql = "
    SELECT
      postcode, longitude, latitude
    FROM
      postcodes
    WHERE
      longitude > latitude
  ";
  q    = new Query(sql = trim(sql), datasource = db);
  data = q.execute().getResult();

  if (structKeyExists(form, "execute")) {
    if (isQuery(data) && data.recordCount > 0) {
      transaction action="begin" 
      { 
        try {
          qUpdate = new Query(
            datasource = db, 
            sql = "UPDATE postcodes SET longitude = :longitude, latitude = :latitude WHERE postcode = :postcode"
          );
          for (x = 1; x <= data.recordCount; x++) {
            writeOutput("<p>" & data["postcode"][x] & "</p>");

            qUpdate.addParam(name = "longitude", value = data["latitude"][x], cfsqltype = "CF_SQL_DOUBLE");
            qUpdate.addParam(name = "latitude", value  = data["longitude"][x], cfsqltype = "CF_SQL_DOUBLE");
            qUpdate.addParam(name = "postcode", value  = data["postcode"][x], cfsqltype = "CF_SQL_VARCHAR");

            qUpdate.execute();
            qUpdate.clearParams();
          }
          transactionCommit();
        } catch (any e) {
          transactionRollback();
          writeOutput("<p>The database transaction failed, rolling back changes</p>");
          writeDump(e);
        }
      }
      writeOutput("#data.recordCount# postcodes have been updated");  
    } else {
      writeOutput("There were no incorrect postcodes found in the database");
    }
  }
</cfscript>
<cfoutput>
  <form name="update" action="" method="post">
    <input type="hidden" name="execute" value="1"/>
    <input type="submit" name="update" value="Update #val(data.recordCount)# Postcodes"/>
  </form>
</cfoutput>

<!--- <cfdump var="#data#"/> --->

ライブサーバーで実行する予定だったので、スクリプトはトランザクションにラップされていますが、スクリプトをローカルでテストした後、1 時間以上実行し続けました!

郵便番号データベースには約 170 万件のレコードが含まれており、3 つの列だけがすべて正しくインデックス付けされpostcode, longitude, latitudeており、最初のクエリで正しい 2,200 の結果が返されます。

ColdFusion admin のコンポーネント キャッシュ設定をチェックして、これがローカルにないかどうかを確認しましたが、オンになっています!

だから私の質問 - なぜこれは実行に時間がかかるのですか?

mysql と ACF 9 を使用しています。

4

2 に答える 2

5

なぜCFでそれを行うのですか?すべてSQLで行うだけで、はるかに高速になります。私はmysqlを使用していませんが、漠然と次のようなものです:

UPDATE postcodes 
SET longitude = newlongitude,
latitude = newlatitude 
FROM (SELECT latitude AS newlongitude, longitude AS newlatitude FROM postcodes 
         WHERE longitude > latitude)
于 2012-10-17T12:40:35.690 に答える
0

実行に時間がかかる理由は、このビットを 2,200 回ループしているためです。

writeOutput("<p>" & data["postcode"][x] & "</p>");

qUpdate.addParam(name = "longitude", value = data["latitude"][x], cfsqltype = "CF_SQL_DOUBLE");
qUpdate.addParam(name = "latitude", value  = data["longitude"][x], cfsqltype = "CF_SQL_DOUBLE");
qUpdate.addParam(name = "postcode", value  = data["postcode"][x], cfsqltype = "CF_SQL_VARCHAR");

qUpdate.execute();
qUpdate.clearParams();

代わりに SQL を使用してこの問題を解決すると、この問題は発生しなくなります。

于 2012-10-17T22:24:54.640 に答える