文章目录
  1. 1. 测试环境
  2. 2. 测试方法
  3. 3. 测试结果

在PHP中查询MySQL数据表是最常用的操作,但一张表中的数据往往不够用,需要关联另一个表或多个表,这时一般有两种选择:

  1. 在查询时合并需要用到的数据表->处理数据(合并查询)
  2. 先查询一个表,获取到相关字段->遍历并查询其它表->处理数据(遍历查询)

这里简单做了下测试,以便对比。

测试环境

* *
服务器 Apache(本地)
MySQL环境 服务器环境
MySQL版本 5.6.16
总字段数 184个(2张表)
查询字段数 17个
查询次数 10个

测试方法

这里用了ThinkPHP3.2.3来进行查询。由于php没有对毫秒级时间戳的原生支持,所以还需封装一个方法来实现:

1
2
3
4
5
// 获取毫秒级的当前时间
function getMillisecond() {
list($t1, $t2) = explode(' ', microtime());
return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}

合并查询的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$startTime = getMillisecond();
// 查询
$list = $Model->table('table1')
->alias('t1')
->join('table2 t2 ON t1.id=t2.id')
->field($fields)
->where($map)
->order('update_time desc')
->limit(5)
->select();
$data = array();
foreach ($list as $key=>$val) {
// ...处理数据
array_push($data, $val);
}
$endTime = getMillisecond();
// json_encode($data);
echo ($endTime - $startTime).'ms';

遍历查询的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$startTime = getMillisecond();
// 查询
$list1 = M('table1')
->alias('t1')
->field($fields['t1'])
->where($map)
->order('update_time desc')
->limit(5)
->select();
$data = array();
foreach ($list1 as $key=>$val) {
$list2 = M('table2')
->alias('t2')
->field($fields['t2'])
->where(array('id'=>$val['id']))
->find();
// ...处理数据
$lists = array_merge($val, $list2);
array_push($data, $lists);
}
$endTime = getMillisecond();
// json_encode($data);
echo ($endTime - $startTime).'ms';

需要注意的是,遍历查询需要把$fields改写为二维数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 合并查询
$fields = array(
't1.xxx as xxx',
't2.xxx as xxx',
// ...
);
// 遍历查询
$fields = array(
't1'=>array(
'xxx as xxx',
// ...
),
't2'=>array(
'xxx as xxx',
// ...
)
);

测试结果

分别对不同的数据量进行了测试

limit(5)

查询方式 合并查询 遍历查询
最快耗时(ms) 962 754
最慢耗时(ms) 1440 1448
平均耗时(ms) 1201 1101

limit(15)

查询方式 合并查询 遍历查询
最快耗时(ms) 1904 1880
最慢耗时(ms) 2371 3078
平均耗时(ms) 2137.5 2479

limit(30)

查询方式 合并查询 遍历查询
最快耗时(ms) 3392 3583
最慢耗时(ms) 3861 5444
平均耗时(ms) 3626.5 4513.5

从数据上看,在数据量不多时,两种查询方式差距不大,甚至遍历查询要快一些。但当数据量越来越大时,合并查询的性能优势就显现出来了。这也很容易理解,因为循环查询时虽然单次的量不多,但须多次连接数据库。如果数据库不在本地服务器,就会增加一定的时间成本。

而且从写法上看,合并查询显得优雅美观一些。因此,如果数据量比较大时,尽量避免遍历查询。

文章目录
  1. 1. 测试环境
  2. 2. 测试方法
  3. 3. 测试结果