简体   繁体   English

多维数组

[英]MultiDimensional Arrays

In Codeigniter, I have the following model 在Codeigniter中,我有以下模型

function get_item_history($id)
{  
  //from metadata_history get item_id and corresponding metadata
  $this->db->from('metadata_history')->where(array('id'=>$id, 'current_revision'=> "TRUE"));
  $query = $this->db->get();
  $result = $query->result_array(); //store this in an array

  // loop through the array
  foreach( $result as $key => $row ) 
  {
   $array = array('item_id'=>$row['item_id'], 'current_revision'=> "TRUE");
   $this->db->from('history')->where($array);
   $query = $this->db->get();
   $row['items'] = $query->result_array(); //
   $result[$key] = $row; 
  }

  return $result;
}

The problem is that this results in multiple queries to the SQL table increasing the execution time significantly (pagination is not an option) 问题是,这导致对SQL表的多个查询大大增加了执行时间(不可分页)

I want to be able to pass the first query results to the second query as an array, so that I would have only a single go at the database, then rebuild an array from the results. 我希望能够将第一个查询结果作为数组传递给第二个查询,这样我就只能一次访问数据库,然后根据结果重建一个数组。

How should I rewrite this code (the second part)? 我应该如何重写此代码(第二部分)? Will it be faster (I suppose so)? 会更快吗(我想是这样)?

EDIT 编辑

Rebuilding the array from the results is what is flummoxing me. 从结果中重建数组真是困扰我。

http://www.phpbuilder.com/board/showthread.php?t=10373847 http://www.phpbuilder.com/board/showthread.php?t=10373847

this is what I probably want, but am failing the jump 这可能是我想要的,但是没有成功

You should use JOINs to do this. 您应该使用JOIN做到这一点。 It'll offload the execution of the query to the server. 它将查询的执行工作卸载到服务器。 I can't give you too much more detail without knowing how your database is structured, but check out the docs on JOINs: 在不了解数据库结构的情况下,我无法为您提供更多详细信息,但请查看有关JOIN的文档:

http://dev.mysql.com/doc/refman/5.0/en/join.html http://dev.mysql.com/doc/refman/5.0/en/join.html

http://www.webdesign.org/web-programming/php/mysql-join-tutorial.14876.html http://www.webdesign.org/web-programming/php/mysql-join-tutorial.14876.html

http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php

Another option would be to do your wheres in the loop and move the query executation outside of the foreach: 另一种选择是在循环中进行操作,并将查询执行移至foreach之外:

// loop through the array
foreach( $result as $key => $row )  
{
        $array = array('item_id'=>$row['item_id'], 'current_revision'=> "TRUE");
        $this->db->or_where($array);
}

$query = $this->db->get();
$row['items'] = $query->result_array(); //
$result[$key] = $row;

You can use inner query here. 您可以在此处使用内部查询。 It is ideal situation for that - 理想的情况是-

function get_item_history($id)
{  

// Here the above requirement can be achieved in a single query.

$sql = "select * from history h 
where h.item_id IN (select item_id from metadata_history mh where mh.id = $id 
AND mh.current_revision = TRUE) AND h.current_revision = TRUE";

$result = $this->db->query($sql);

//Return whichever column of result you want to return or process result if you want.

$result;
}

OK this took some work, and I also had to do some adjustments in my view 好的,这需要一些工作,而且我还必须做一些调整

So the problem can be broken down into two main components 因此,问题可以分为两个主要部分

1) Pass the results of the first query as an array to the second one using where_in 1)使用where_in将第一个查询的结果作为数组传递给第二个where_in

2) Reorder/regroup the results of the first array by item_id 2)通过item_id对第一个数组的结果重新排序/重新item_id

My earlier code was doing the second component implicitly 我之前的代码隐式地做第二个组件

So here is what I did (limits, offsets, ordering have been cut out to improve readablity) 所以这就是我所做的(限制,偏移量,顺序已被切除以提高可读性)

function get_item_history($id)
{  
 //from metadata_history get item_id and corresponding metadata
 $this->db->from('metadata_history')->where(array('id'=>$id, 'current_revision'=> "TRUE"));
 $query = $this->db->get();
 $result_query1 = $query->result_array(); //store this in an array




foreach ($result_query1 as $key-> $row){
$result[$row['item_id']]['meta_info'] = $row; //the first query contains meta info, that must be passed to the view
$selected_id_array[] = $row['item_id'];  //Create a  array to pass on to the next query
$result[$row['item_id']]['items'] = array(); //declare an array which will hold the results of second query later
}


$this->db->select('h.*');
$this->db->from('history h');
$this->db->where_in('h.item_id', $selected_id_array);
$this->db->where(array('h.current_revision' => 'TRUE'));
$query = $this->db->get();

$row = $query->result_array();


        foreach ($row as $key => $datarow) {

        $result[$datarow['item_id']]['items'][] = $datarow; //populate the array we declared earlier with results from second query
}




return $result; // Now this variable holds an array which is indexed by item id and contains the results of second query 'grouped' by item_id
 }

So the number of queries have been cut from ~10 to 2. On my local machine this saves ~50 msec/page, though I am not sure how this will do for larger databases. 因此,查询数量已从约10个减少到2个。在我的本地计算机上,这可以节省大约50毫秒/页,尽管我不确定这对大型数据库的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM