我目前正在为另一软件构建API;我们正在使用具有跨国替换功能的令牌ID来维护用户授权。我们正在尝试确定更快(且占用更少资源)的模式来完成嵌套if语句的任务(我们是否应该使用php来操作if语句或允许mysql引擎完成任务。
请注意,同一台服务器正在运行MySQL和PHP,因此通过在两台服务器之间分割参数,没有负载转移的好处。
我们看到的选项如下:
PHP驱动的if语句
$sql = $conn->prepare("SELECT uid
,ukey
FROM token
WHERE ukey = :ukey AND uid = :uid AND timeexp >= now()");
$sql->execute(array('ukey' => $curtoken, 'uid' => $uid));
$result = $sql->fetchAll();
if ( count($result) ) {
//New MySQL Statement to run our action
}
或使用mysql if / where语句
INSERT INTO TABLE
SELECT value_for_column1, value_for_column2, ...
FROM wherever
WHERE ((SELECT count(*) FROM `Token` WHERE ukey = :ukey AND uid = :uid AND timeexp >= now()) =1)
答案 0 :(得分:1)
可以在几个地方进行优化。
索引
由于select ukey, uid...where ukey = :ukey AND uid = :uid...
使用ukey,uid对,因此将复合索引放在ukey + uid上可能会有价值。
INSERT的子查询也使用这2列,并且可以从索引中受益。但是,如果有50-100行,我怀疑索引是否会产生重大影响。表扫描可能同样快。如果该表将成为几千条记录,请考虑复合索引。
要求计数而不是字段
如果要从select ukey, uid...
切换到select count(*)
,则从数据库返回的数据将是一个数字。在应用程序和数据库之间使用的位数将更少,并且吞吐量将提高。我不知道这种改进是否会引起人们的注意,除非大规模进行。
可能会有与PHP相关的好处。代替$result = $sql->fetchAll()
,您可以使用$count = $sql->fetchColumn()
直接在变量中获取计数。然后,PHP可以使用if ($count > 0) ...
存在的地方
WHERE (
SELECT count(*)
FROM `Token`
WHERE ukey = :ukey AND uid = :uid AND timeexp >= now() = 1
)
可以替换为以下内容:
WHERE EXISTS (
SELECT 1 FROM `Token`
WHERE ukey = :ukey AND uid = :uid AND timeexp >= now())
)
这样,就不需要count(*)
并将其与1进行比较。
您已经很好地完成了定期清除信息以保留少量干净数据集的工作。这将有助于查询和扩展。