我在MySQL数据库中大约有500,000条个人资料记录,其中包含一个生日日期列(dob)。由于必须获得每个配置文件的年龄,因此我需要动态地计算它,可以通过PHP (date_diff(date_create($dob), date_create('today'))->y)
或SQL ('SELECT TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age')
进行计算。
两者中哪个更快或更优选,特别是如果我有成千上万的行?
答案 0 :(得分:3)
通常,最好的方法是在服务器上进行此类计算。
理想的方法是使用生成的列。自MySQL 5.7.5起,该功能已可用,并表示为:
alter table t add age unsigned as
(TIMESTAMPDIFF(YEAR, dob, CURDATE()));
A,您只能将确定性函数用于生成的列。 curdate()
和now()
不确定,因为每次调用它们的值都会改变。
下一个最好的方法是使用视图:
create view v_t as
select t.*,
TIMESTAMPDIFF(YEAR, dob, CURDATE())
from t;
然后,当您查询视图时,将得到age
。无论在哪里查询,都是如此。到处都是相同的逻辑。
在服务器上进行计算的唯一警告是它使用服务器时间,而不是本地应用程序时间。如果这是一个问题,那么这是在本地进行计算的有力论据。
答案 1 :(得分:0)
这是一个测试:
创建一个随机日期为100K的表格
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的性能。
答案 2 :(得分:-1)
如果要获取所有500,000条记录,则应在MySql中执行此操作,因为性能优于PHP
但是,如果要获取某些数据(例如10条记录),请使用PHP进行处理,最好处理。和性能没什么不同