2013-02-20 52 views
3

首先,我要感謝你在頁面上的所有幫助,這真的很有幫助。現在我遇到了一個我無法弄清楚的情況,我希望你能幫助我,就是這樣:Oracle/Mysql編輯大量記錄,建議?

在我的工作場所,我可以訪問一個Oracle數據庫,其中包含一個用戶名(表名姓氏,出生日期和其他東西)。它有1700萬條記錄,並且對於每條記錄我需要生成一個唯一的密鑰(可以說它是名稱的兩個第一個字母加上出生日期連接,實際上是更復雜的,但它是一個例子),所以對於我需要的這個密鑰檢索記錄,計算密鑰,然後用密鑰更新記錄。現在超過1700萬條記錄它正在殺死服務器!

因此,在工作的數據庫是甲骨文,我把數據複製到我的機器到MYSQL數據庫進行測試。我打算在本地測試使用php進行計算,然後創建一個Java應用程序來在服務器上創建密鑰,但這是一個巨大的工作量!我不知道要走哪條路。簡單的選擇需要10分鐘的PHP(在MySQL上通過命令行需要1.49分鐘COUNT()的記錄)

我知道計算鍵記錄進來時更好。它們到達包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; 

做在PHP代碼//最後,我連接第一二煤焦在名稱中與計算得到的代碼和BIRTHDAY EX:JH235408071984將來自FOR JHON出生於1984年8月7日與NAME CODE計算值= 2354

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

希望它可以幫助和你可以給我一些指導!

+0

可能沒有什麼幫助,但以我的經驗(PHP + Oracle 10g2)來處理大數據,一種可能的方法是將其分成幾個相對較小的塊,更新100條記錄,更新ID 1-10,然後11-20等等。並且記得在「空閒」時間(例如晚上)做這個,並準備好聲明。 – Passerby 2013-02-20 04:56:32

回答

1

我一般做當面對堆積如山像這樣的數據集,首先放在某處以跟蹤我的位置(只有一張桌子可以完成這項工作),然後一次運行1000次左右的結果。假設你不需要最大程度的精確度來計算出有多少記錄(假設沒有巨大的漏洞),並且爲了循環使用數據,我們可以獲得近似數量的結果查詢如:

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

假設您有一個名爲ID的PK標識。與完整的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併爲它們創建唯一值)。

無論如何,如果沒有別的東西,希望能幫助你獲得開始!

+0

非常感謝,我會嘗試它,看看如何它現在,我有疑問,$ MyDB-> GetSingleRow($ query);工作?因爲我的第一次反應是當我在桌面上進行選擇時,即使我使用限制1,10(例如),它在處理和獲取結果上花費了大量時間,對此有什麼幫助? – 2013-02-20 18:33:42

+0

GetSingleRow只是框架中的一個函數示例,所以我不需要特定的mysqli,PDO,Oracle或任何您正在使用的接口。我不希望在進程的每個部分都進行查詢,獲取結果,修改它們是否存在,等等。它只會從查詢中獲取一行。 如果做一些簡單的事情,比如限制1,10需要很長時間來處理,那麼您在查詢的任何字段中是否存在關鍵字?這聽起來好像沒有,查詢必須抓取整個表才能找到結果。例如,「選擇*從表WHERE ID = 1」 - 把一個關鍵的ID – 2013-02-20 19:00:37

+0

對不起的錯字,我的第一個TROUBLE是當我做了一個選擇.... – 2013-02-20 20:04:20

1

您不必使用php進行計算,首先爲您的表添加unique_key列,然後在此列上創建索引/唯一約束,之後您可以使用sql更新整個表一次,generated_value爲unique_key一排,而不是由PHP

update table set unique_key = generated_value 

SQL中計算,在此之後,如果你想找到的人,你會計算其unique_key,然後使用查詢

select * from table where unique_key = generated_value 
+0

非常感謝你的回答,現在@ogres,希望你能進一步幫助我,我會給出更多細節,我需要生成的關鍵是通過使用namen和birthadates以及一系列數字的一系列計算完成的,我可以直接從SQL中計算出來嗎? – 2013-02-20 16:10:30

+0

好吧,我明白了,我現在還不知道如何才能使用sql來計算這個值,我需要使用名字,姓氏,birtdate和一個包含素數的表來執行一系列計算,是否可以完成只使用SQL? – 2013-02-20 20:22:25

+0

給我舉例計算在PHP或在語言中使用,我會盡力幫助您 – ogres 2013-02-22 05:44:38