我遇到的问题是海量数据的表,每个表大约百万条,每天会生成一个表。
我查询的时候是这样写的 在foreach 循环里写sql语句:$tableArr是表数组,如果查询的是1到3号的数据 这个数组是
array([0]=>table_20101001,[1]=>table_20101002,[2]=>table_20101003)
foreach($tableArr AS $table)
{
$sqlCnt ="SELECT COUNT(*) FROM $table h"
 ." WHERE ". $where;
$total += $tabcnt[$table] = $this->_gdb -> fetchOne($sqlCnt);
}
这样写把每个表的记录数加起来,最后$total是总记录数用于分页
再下面也是循环写的:
foreach($tableArr AS $k => $table)
{
    $cntArr[] = $tabcnt[$table];
    $sqlT = "SELECT CONCAT(h.id,'-$table') AS it,FROM_UNIXTIME(h.time) AS fmtdate,h.src_ip,h.url,"
." (h.ul_flux + h.dl_flux) AS totalflux, h.user_id, h.rule_id FROM $table h"
." WHERE  ".$where. " ORDER BY h.time DESC LIMIT $offset,".$limit;     $data = $this->_gdb -> fetchAll($sqlT);
    $res = array_merge($res, $data);     $cnt = count($data);
    $cnts += $cnt;
    if ($cnts >= _DATA_PER_PAGE_LOG)
    {
break;
    }
    else
    {
$limit = _DATA_PER_PAGE_LOG - $cnt;
if ($cnt > 0 && $cnt <= _DATA_PER_PAGE_LOG)
{
    $offset = 0;
    continue;
}
else
{
    $offset = (array_sum($cntArr)) - ($page-1)*_DATA_PER_PAGE_LOG;
    $offset = $offset > 0 ? $offset : -$offset;
}
    }
}
return $res;
}
不知道这么写的效率和用union联合的一条sql语句查询的效率哪个高?请高手赐教!
另外我写这段代码:
$cnt = count($data);
    $cnts += $cnt;
    if ($cnts >= _DATA_PER_PAGE_LOG)
    {
break;
    }
    else
    {
$limit = _DATA_PER_PAGE_LOG - $cnt;
if ($cnt > 0 && $cnt <= _DATA_PER_PAGE_LOG)
{
    $offset = 0;
    continue;
}
else
{
    $offset = (array_sum($cntArr)) - ($page-1)*_DATA_PER_PAGE_LOG;
    $offset = $offset > 0 ? $offset : -$offset;
}
    }
的目的是减少循环时多个表之间的衔接问题,比如第一个表数据记录数不满足每页显示的数目那么第二表该从哪里(limit m,n)查起,大家有没有好的方法?

解决方案 »

  1.   

    百万数据,这样查应该会超时吧,最起码不要在sql语句中写函数吧,数据量那么大,Select * From table  Where ID>=(
    Select Max(ID) From (
     Select ID From from Order By ID limit 90000,1
    ) As tmp
    ) limit 29;用这种模式做翻页应该效率会高一些
      

  2.   

    select * from table limit (select * from table where id < n), x
      

  3.   

    select * from table limit (select * from table where id > n), x
      

  4.   

    Select * From table Where ID>=(
    Select Max(ID) From (
     Select ID From from Order By ID limit 90000,1
    ) As tmp
    ) limit 29;
    用这种模式做翻页应该效率会为什么会高呢?
      

  5.   

    循环里查询不知道这么写的效率和用union联合的一条sql语句查询的效率哪个高?请高手赐教!
      

  6.   

    尽量利用SQL语句和SQL函数来完成可能的功能,而避免自己在循环里去查。因为DBS会优化SQL语句的执行,效率要高得多。大多数效率不理想的原因,都是因为没有这样而造成的。
      

  7.   

    楼上,mysql支持子查询嵌入limit?你这个代码肯定运行不了
      

  8.   

    To 楼上, 的确是可以运行的, 那个限制是老版本的...虽然我对这个查询的效率是否更高很表怀疑TO 楼主, 
    看起来是个log表, 可以考虑使用archive引擎, 当然前提是你不需要修改操作(log似乎应该不需要).
    archive表不支持order by,而且select会做全表扫描,所以你的程序肯定需要调整.如果不能转archive表,需要看你的where情况才能做优化, 
    个人觉得使用union all应该差不多, 你可以测试一下啊后面一个问题,要是我坚决改掉需求,不做跨日期的分页........