Oracle / Mysql编辑大量记录,建议?

时间:2013-02-20 04:12:41

标签: java php mysql oracle

首先,我要感谢您在页面上提供的所有帮助,这非常有帮助。现在我遇到了一个我无法弄清楚的情况,我希望你能帮助我,就是这样:

在我的工作场所,我可以访问一个带有用户表的Oracle数据库(名称,姓氏,生日和其他内容)。它有1700万条记录,并且对于每条记录我需要生成一个唯一的密钥(假设它是名称的2个首字母加上连接的生日,实际上更复杂,但它是一个例子),所以对于这个密钥我需要检索记录,计算密钥,然后用密钥更新记录。现在超过1700万条记录正在杀死服务器!!

所以工作中的数据库是Oracle,我将数据复制到我的机器上,进入MYSQL数据库进行测试。我正计划在本地进行测试,使用php进行计算,然后创建一个java应用程序来在服务器上创建密钥,但这是一个巨大的工作量!我不知道该走哪条路。简单的选择在php上需要10分钟(在mysql上通过命令行需要1.49分钟到COUNT()记录)

我知道随着记录的进入计算密钥会更好。它们以500k的包装到达,但由于我刚到这里,数据已经合并,我必须处理这些记录。

那么你会推荐这个可怜的灵魂来完成这样的任务。我在考虑触发器或pl / sql,但我真的迷失在性能方面会更好。

非常感谢!!!

-----------作为来自食人魔的请求,并希望你能帮助我,这里是php中的代码,我需要为每一行做计算

$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; 

//最后我用计算出的代码和生日EX:JH235408071984将名字中的第一个两个字符连接起来于1984年8月7日来自JHON BORN,计算名称代码= 2354

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

希望它有所帮助,你可以给我一些指示!!

2 个答案:

答案 0 :(得分:1)

你不必使用php进行计算,首先,将unique_key的列添加到你的表中,然后在这个列上创建索引/唯一约束,之后你可以用sql更新整个表一次,generated_value是unique_key for a行,在SQL中计算而不是由php

计算
update table set unique_key = generated_value

,之后如果你想找人,你将计算其unique_key,然后使用查询

select * from table where unique_key = generated_value

答案 1 :(得分:1)

当面对像这样的庞大数据集时,我通常会做的事情是首先留在某处以跟踪我的位置(只需要一个表就可以完成这项工作),然后一次运行1000个左右的结果。假设您不需要最大程度的准确性来确定将会有多少记录(假设没有巨大的间隙孔),并且还使用数据进行循环,我们可以获取大约的结果数#像这样的查询:

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

假设您有一个名为ID的PK Identity。与完整的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并为它们创建唯一值)。

无论如何,希望能帮助你在没有别的的情况下开始!