第一个问题:最近项目做统计遇到很多性能的问题,需要循环从数据库取数据,优化思路是先把所有数据都从数据库取出来,做一个缓冲,然后在循环内从缓冲去查找,我们需要从这二维数据里根据某列的某个值找到该行的数据,例缓存数据是:array(2093) {
  [0]=>
  array(12) {
    ["id"]=>
    int(45)
    ["level"]=>
    int(2)
    ["parent_id"]=>
    int(7134)
  }
  [1]=>
  array(12) {
    ["id"]=>
    int(7134)
    ["pid"]=>
    int(3)
    ["parent_id"]=>
    int(0)
  }
  [2]=>
  array(12) {
    ["id"]=>
    int(7133)
    ["pid"]=>
    int(45)
    ["level"]=>
    int(2)
    ["parent_id"]=>
    int(7129)
  }
  [3]=>
  array(12) {
    ["id"]=>
    int(7132)
    ["pid"]=>
    int(45)
    ["level"]=>
    int(2)
    ["parent_id"]=>
    int(7129)
  }}   现在我们做了一个查找的函数function getRowByKeyVal($array,$key,$val,$f)
{

/*while (list($k) =each($array))
{

if($f=='like'){
if(strstr($array[$k][$key],$val))
return  $array[$k];
}
else{
if($array[$k][$key]==$val)
return  $array[$k];
}
}*/

/* foreach($array as $k=>$v)
{

if(in_array($val,$v)){
return  $array[$k];
}
}*/

foreach($array as $k=>$v)
{
if($f=='like'){
if(strstr($v[$key],$val))
return  $array[$k];
}
else{
if($v[$key]==$val)
return  $array[$k];
}
} }   实践当总数据超过2000多条,性能基本没有提升,也想过查找用二分算法,但是这个算法前提必须是查询列是有序数据。  
第二个问题:excel导出,遇到几千行,很慢。
第三个问题:网站上有项目完成了,需要把照片全部打成压缩包导出去,有时候几个G大小,这个怎么处理比较好啊?
希望有经验的人,指点一二。

解决方案 »

  1.   

    提供个思路,转为key=>value方式保存,方便搜寻。
      

  2.   

    例如id的
    则保存为
    array(
    45 => array(),
    7133 => array(),
    7134 => array()
    );
      

  3.   

    但是我每次查找的key是不固定啊,我可能查询id=45或者level=2的啊
      

  4.   

    要学会相信别人,缺乏团队精神将一事无成!
    能在数据库中完成的,就不要用代码完成
    你自己实现所谓缓存,绝不会比专业人士制造的数据库效率更高
    php 提供了 array_search 函数,可以方便的在数组中进行查找,无需劳烦你去 foreach
    你缓存的数组应是 var_export 函数的结果,这样就可以方便的用 include 载入如果你坚持输入 excel 的原生二进制数据,那么慢是必然的
    但你采用他兼容的 html 格式输出,那么连程序都不需要怎么改动,就可将页面编程 excel
      

  5.   

     array_search能直接根据id=2这种 查找二维数组吗? 
      

  6.   

    $ar = array(
      array("id" => 45, "level" => 2, "parent_id" => 7134),
      array("id" => 7134, "pid" => 3, "parent_id" => 0),
      array("id" => 7133, "pid" => 45, "level" => 2, "parent_id" => 7129),
      array("id" => 7132, "pid" => 45, "level" => 2, "parent_id" => 7129),
    );
    $k = 'id';
    $n = 7133;
    $r = array_filter($ar, function($v) use ($k, $n) { return $v[$k] == $n; });
    print_r($r);Array
    (
        [2] => Array
            (
                [id] => 7133
                [pid] => 45
                [level] => 2
                [parent_id] => 7129
            ))
      

  7.   

    我觉得既然数据在db,应该直接在db中查找,然后把查找的结果保存到缓存。待下次使用相同条件查找时,直接返回缓存数据。
    而不是先把所有数据保存到缓存再查找,因为db查找比你使用php查找数组快。例如你要查找id=2 或id=7132的记录$where = 'id=2 or id=7132';
    $sql = "select * from table where ".$where;
    然后得到结果是result
    这时可以创建缓存
    array(
    'key' => result
    );key的值可以是where条件的md5,例如 $key=md5('id=2 or id=7132');
    $cache = array();
    $cache[$key] = $result;
    下次搜寻前,先判断当前搜寻条件的md5值是否存在于cache,如存在直接返回$key=md5('id=2 or id=7132');
    if(isset($cache[$key])){
        return $cache[$key];
    }else{
        // 连接数据库查询
    }
      

  8.   


    好像这样的思路不是很行,我是c#转过来写PHP的,用的是wecenter的一个问答系统二次开发的,他从db中获取数据对join的支持很不行,所以导致我们很多统计先要把主表数据查询出来 然后再去从表查找相应的属性数据,可能这个循环有两三级,而且条件都不一样。所以这个模式第一次都很慢,第二次才快的起来, 但是好多统计第一次能查出来都不容易。
      

  9.   

    第一次很慢,那就是你系统不支持join的查询,需要一层层查询,第一次没有缓存,当然就慢了。
    除非你修改表结构,或是系统支持join。或者你每隔一分钟,就创建一个适合查询的临时表,这个表只用作查询,把需要的字段都先写入这个表,避免join的问题。如果还是想用缓存的,思路是可以照用的
    首先,定义key那里,一样使用搜寻条件md5的值,但不直接使用string保存,而是使用json例如需要查
    id=2 or id=7132
    之前写法是
    $where = 'id=2 or id=7132';
    现在改为
    $where = array(
    array('id'=>2),
    array('id'=>7132),
    );然后 $key = md5(json_encode($where));
    不过你拿到$where数组时,需要自己分析这个查查询条件,适应多层的查询。后面一样,多层查询后保存在cache,读取时根据条件创建$key,再判断cache存在则直接返回cache内容
    $where = array(
        array('id'=>2),
        array('id'=>7132)
    );
    $key=md5(json_encode($where));
    if(isset($cache[$key])){
        return $cache[$key];
    }else{
        // 连接数据库查询,把查询结果写入cache
    }