计算年龄:php与mysql,哪种方法更好?

mpgws1up  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(432)

我在mysql数据库中有大约500000条个人资料记录,其中包含一个birthdate列(dob)。因为我必须得到每个配置文件的年龄,所以我需要动态地计算它,我可以通过php来做 (date_diff(date_create($dob), date_create('today'))->y) 或通过sql ('SELECT TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age') . 哪一个更快或更受欢迎,尤其是如果我有数十万行?

wlzqhblo

wlzqhblo1#

一般来说,最好的方法是在服务器上进行这种计算。
理想的方法是使用生成的列。从MySQL5.7.5开始就有了,可以表示为:

alter table t add age unsigned as 
    (TIMESTAMPDIFF(YEAR, dob, CURDATE()));

唉,您只能对生成的列使用确定性函数。 curdate() 以及 now() 不是确定性的,因为它们的值可以随着每次调用而改变。
下一个最好的方法是使用视图:

create view v_t as
    select t.*,
           TIMESTAMPDIFF(YEAR, dob, CURDATE())
    from t;

然后,当您查询视图时,您将得到 age . 无论你在哪里质疑它,这都是正确的。到处都是同样的逻辑。
在服务器上进行计算的唯一警告是,它使用服务器时间,而不是本地应用程序时间。如果这是一个问题,那么这就是在本地进行计算的有力理由。

vlurs2pr

vlurs2pr2#

下面是一个测试:
创建一个包含10万个随机日期的表

drop table if exists birthdays;
create table birthdays (
    id int auto_increment primary key,
    dob date
);
insert into birthdays (dob)
    select '1950-01-01' + interval floor(rand(1)*68*365) day as dob
    from information_schema.COLUMNS c1
       , information_schema.COLUMNS c2
       , information_schema.COLUMNS c3
    limit 100000
;

运行此php脚本

<?php
header('Content-type: text/plain');
$db = new PDO("mysql:host=localhost;dbname=test", "test","");

### SQL

$starttime = microtime(true);

$stmt = $db->query("SELECT id, dob, TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age FROM birthdays");
$data = $stmt->fetchAll(PDO::FETCH_OBJ);

$runtime = microtime(true) - $starttime;
echo "SQL: $runtime \n";

### PHP

$starttime = microtime(true);

$stmt = $db->query("SELECT id, dob FROM birthdays");
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($data as $row) {
    $row->age = date_diff(date_create($row->dob), date_create('today'))->y;
}

$runtime = microtime(true) - $starttime;
echo "PHP: $runtime \n";

结果:

SQL: 0.19094109535217 
PHP: 1.203684091568

看起来sql解决方案的速度快了6倍。但事实并非如此。如果我们从两个解中删除计算年龄的代码,我们将得到0.1653790473938。这意味着sql的开销是0.025秒,而php是1.038秒。所以在这个测试中,sql的速度快了40倍。
注意:在php中有更快的方法来计算年龄。例如

$d = date('Y-m-d');
$row->age = substr($d, 0, 4) - substr($row->dob, 0, 4) - (substr($row->dob, 5) > substr($d, 5) ? 1 : 0);

速度快了四倍 date('Y-m-d') 消耗超过80%的时间。如果你想办法避免任何日期函数,你可能会接近mysql的性能。

tf7tbtn2

tf7tbtn23#

如果你想得到所有500000条记录,你应该在mysql中这样做,因为性能比php好
但是,如果您想获取其中的一些数据(例如10条记录),那么使用php处理这些数据会更好。性能也没什么不同

相关问题