私は Postgresql の pgsql や C についてあまり知らないので、これはちょっと難しい問題です。
基本的な制御構造をレイアウトするか、PHP で行っている方法に代わる方法を提案して、この操作を高速化することで、誰かがこれを開始できることを願っています。
ここでは、基本的な概要を説明します。以下のコード。
インテーク テーブルに行があります。これは、プロバイダーの正規化データベース内の既存のプロバイダーと一致する場合と一致しない場合があります。行の完全性に応じて、さまざまなデータ要素があります。
現在のコントロール関数は次のようになります。既存のプロバイダーの ID を返すか、新しいプロバイダーを作成してからその ID を返すことが仕事です。
function find_provider($input){
if (!$by_i_id = $this->find_provider_with_i_provider_id($input->i_provider_id)){
//Not By I ID
if (!$by_medicare_id = $this->find_provider_with_medicare_id($input->national_provider_id)){
//Not by Medicare ID
if (!$by_license_number = $this->find_provider_with_license_number($input->license)){
//Not by License Number
if (!$by_s_id_map = $this->find_provider_with_s_provider_id($input->source_id, $input->s_client_id, $input->s_provider_id)){
//Not By S_id
if (!$by_tax_id = $this->find_provider_with_tax_id($input->tax_id, $input->s_entity_type, $input->source_id, $input->last_name, $input->first_name)){
//Not by Tax Id
if (!$by_name = $this->find_provider_by_name($input->first_name, $input->last_name)){
//not by Name.
return $this->add_provider($input);
}else{
//At least 1 Name Match
if (count($by_name) == 1){
$by_name = $by_name[0]->provider_id;
if (!$by_address = $this->confirm_provider_by_address($input->address1, $input->zip, $by_name)){
//Not a Match
return $this->add_provider($input);
}else{
return $by_name;
}
}else{
//More than 1 Match
$match = array();
Foreach ($by_name as $key => $row){
If ($this->confirm_provider_by_address($input->address1, $input->zip, $row->provider_id) != FALSE){
$match[] = $row->provider_id;
}
}
if (count($match)> 0){
return $match[0];
}else{
return $this->add_provider($input);
}
}
}
}else{
return $by_tax_id;
}
}else{
return $by_s_id_map;
}
}else{
return $by_license_number;
}
}else{
return $by_medicare_id;
}
}else{
return $by_i_id;
}
}
この例では、最初に内部 ID、次にメディケア ID、ライセンス、ソース ID、納税者 ID、名前と住所の順で照合を試みます。
これらの関数のそれぞれは次のようになります: (etype は、存在する場合も存在しない場合もあるエンティティ タイプです。また、Not This ID は、これらの関数を 2 回目に実行し、2 番目の一致を探しているためです。 2 つの異なるプロバイダーから同時に)。
function find_provider_with_i_provider_id($provider_id, $etype = null, $notthisid=null){
//Select from provider where 'id' == $provider_id
if (is_int($provider_id)==true && $provider_id != 0){
$this->db->select('id');
$this->db->from('list_provider');
$this->db->where('id', $provider_id);
if (!$etype == null){
$this->db->where('entity_type_id', $etype);
}
if (!$notthisid == null){
$this->db->where('id !=', $notthisid);
}
$result = $this->db->get();
if ($result->num_rows == 0){
return false;
}elseif ($result->num_rows == 1){
//Call The Result Function to Pull the Data as an Object.
$out = $result->result();
return $out[0]->id;
//return true;
}else{
$out = $result->result();
//$this->log_event('find_provider_with_i_provider_id','error', 'Multiple Results for an Internal Provider ID', $provider_id);
return $out[0]->id;
}
}else{
return false;
}
}
ご覧のとおり、これは多くのデータベース作業であり、多くの行を処理する必要があります (現在、取り込みテーブルで 3,500 万)。これがスーパースローです。
PHPでこれをより適切に構造化する方法、またはより理想的には、このすべてをpgsqlに書き直して、データベースがこれをすべて事前に計画および最適化できるようにする方法を見つけようとしています。
データベースは適切にインデックス化されていると思いますが (すべての選択要素と結合要素)、これらの 3500 万行を実行するには、まだ 2 週間ほどかかります。
考え?ヘルプ?
さらに詳しい情報が必要な場合やご不明な点がございましたら、お知らせください。データベースは、結合が機能しないさまざまなユースケースで 1 つまたは 2 つの情報を複製する必要があったことを除いて、ほぼ正規化されています。基本的には雪の結晶のパターンです。