3

まず最初に、このページでお世話になったことに感謝したいと思います。本当に役に立ちました。今、私は理解できない状況に遭遇しました。あなたが私を助けてくれることを願っています.これはそれです:

私の職場では、ユーザー (名前、姓、生年月日など) で満たされたテーブルを持つ Oracle DB にアクセスできます。1700 万のレコードがあり、レコードごとに一意のキーを生成する必要があります (名前の最初の 2 文字と生年月日を連結したものであるとしましょう。実際にはもっと複雑ですが、例です)。レコードを取得するには、キーを計算し、そのキーでレコードを更新します。現在、1,700 万件を超えるレコードでサーバーが停止しています。

したがって、作業中のDBはOracleです。テストのために、マシンのデータをMYSQLデータベースにコピーしました。phpで計算をローカルでテストしてから、Javaアプリケーションを作成してサーバー上でキーを作成する予定でしたが、それは膨大な作業負荷です!! どちらに行けばいいのかわからない。単純な選択はphpで10分かかります(コマンドライン経由のmysqlでは、レコードをCOUNT()するのに1.49分かかります)

レコードが入ってきたらキーを計算したほうがよいことはわかっています。それらは 500k のパッケージで届きますが、ここに来たばかりなので、データはすでにマージされており、これらのレコードで作業する必要があります。

では、この可哀想な魂に、そのような仕事について何をするよう勧めますか? トリガーまたは pl/sql を考えていましたが、パフォーマンスの点で何が良いか本当に迷っています。

どうもありがとうございました!!!

-----------鬼からのリクエストとして、あなたが私を助けてくれることを願っています.

$vn=0;//holds the value calculated for name
$sql="select * from roots";//table holding triplets for character|number (ex: 1|A|13), field names (consecutive|character|code)
$resultados=mysql_query($sql,$idcon);
while($dato=mysql_fetch_array($resultados))//i put all of the pairs in an associative array for quicker acces
{
    $consulta[$dato['v_propio']]=array($dato['caracter'],$dato['v_primo']);
}
//coding the name, for every char in the name i add to $vn, the consecutive times the position of the character in the string, plus the code for the character, if null, i add some values
$pos=1;
for ($i=0;$i<strlen($nombre);$i++)
{
    $char=substr($nombre,$i,1);
    $char=charnum($char);
    if($char!=NULL)
    {
    $vn=$vn+($char*$pos)+$consulta[$char][1];
    }
    else
    $vn=$vn + 28 + 107;
    $pos++;
}
//end of name coding
// i format the code for the name to 4 digits
if ( $vn < 1000 and $vn > 99 )
    $vn = '0'.$vn ;
else if ( $vn < 100 and $vn > 9 ) 
    $vn = '00'.$vn; 
else if ( $vn < 10 ) 
    $vn = '000'.$vn; 
 else
    $vn=$vn; 

//最後に、名前の最初の 2 文字を、計算されたコードと誕生日を連結します。例: JH235408071984 は、1984 年 8 月 7 日に生まれた JHON の名前コード計算 = 2354 に由来します。

$CODE=trim(substr($nombre,0,2)).trim($vn).formatFecha($fnac);

それが役に立てば幸いです、そしてあなたは私にいくつかのポイントを与えることができます!!

4

2 に答える 2

1

このような巨大なデータセットに直面したときに私が一般的に行うことは、まず自分がどこにいるかを追跡するためにどこかに取っておき (1 つのテーブルだけで十分です)、一度に 1000 ほどの結果を実行します。レコードがいくつになるかを正確に把握する必要がないと仮定すると (巨大な穴がないと仮定して)、ループにデータを使用するために、次のようにして結果のおおよその数を取得できます。次のようなクエリ:

SELECT MIN(ID) AS MinID, MAX(ID) AS MaxID FROM Users

ID という名前の PK ID があるとします。このクエリは、完全な COUNT(*) または COUNT(1) と比較して、非常に高速です。次に、上記のテーブルをテストして、データが存在するかどうかを確認し、存在しない場合は最初から開始し、存在する場合は中断したところからそれらの ID の作業を開始できます。これはおそらく非常に多くのレコードで非常に長い時間実行する必要がありますが、必要に応じて再実行できるようにするか、完了するまで永久に実行できるようにすることができます。

それは次のようになります(どのプラットフォームを使用するかどうかわからないため、疑似関数がたくさんあります):

define("NUM_PER_ITERATION", 1000);

// Get our ID range
$query = "SELECT MIN(ID) AS MinID, MAX(ID) AS MaxID FROM Users";
$array = $MyDB->GetSingleRow($query);
$minid = (int) $array["MinID"];
$maxid = (int) $array["MaxID"];

// Get our last starting point
$startingpoint = LoadLastWorkPosition();
if (!$startingpoint || $startingpoint < $minid) {
  $startingpoint = $minid;
} else if ($startingpoint > $maxid) {
  echo("Already done!");
  exit;
}

// Run through the values
$curstart = $startingpoint;
while ($curstart <= $maxid) {
  $curend = $curstart + NUM_PER_ITERATION - 1;

  // Set a time out so it will keep running, you'll know way better
  // than I how long this should be for each loop
  set_time_limit(300);

  // Handle a number of results
  HandleResults($curstart, $curend);

  // Set the start of the next entry
  $curstart = $curend + 1;

  // Save our current progress
  SaveLastWorkPosition($curstart);
}

echo("All done!");

LoadLastWorkPosition (最後の位置をロードしようとし、0 または false または何もない場合は何でも返す)、SaveLastWorkPosition (中断した場所を追跡できるように...別のスクリプトを許可する) を設計する必要があります。値をチェックして、進行状況バーまたは追跡の場所を確認する) および HandleResults (特定の範囲の ID を読み込み、それらの一意の値を作成する)。

とにかく、他に何もないとしても、それがあなたのスタートに役立つことを願っています!

于 2013-02-20T05:28:13.743 に答える
1

計算にphpを使用する必要はありません。最初にunique_keyの列をテーブルに追加してから、この列にインデックス/一意の制約を作成します。その後、sqlでテーブル全体を1回更新できます。生成された値は行のunique_keyです。 PHPではなくSQL内

update table set unique_key = generated_value

、この後、 person を見つけたい場合は、その unique_key を計算してから query を使用します

select * from table where unique_key = generated_value
于 2013-02-20T05:19:11.557 に答える