Php 用mysql优化嵌套if语句

Php 用mysql优化嵌套if语句,php,mysql,Php,Mysql,我目前正在为另一个软件构建API;我们正在使用一个令牌id来替换用户授权维护。我们试图确定完成嵌套if语句任务的快速和资源密集度较低的模式,是应该使用php来操作if语句,还是允许mysql引擎完成任务 可以注意到,同一台服务器正在运行MySQL和PHP,因此在两台服务器之间拆分参数并不会带来负载转移的好处 我们的选择如下: PHP驱动的if语句 $sql = $conn->prepare("SELECT uid ,ukey

我目前正在为另一个软件构建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)

有几个地方可以进行优化

索引

因为选择ukey,uid…其中ukey=:ukey和uid=:uid。。。使用ukey,uid对,在ukey+uid上放置复合索引可能有价值

INSERT有一个子查询,它也使用这两列,并且可以从索引中获益。然而,若有50-100行,我怀疑索引是否会有显著的影响。表格扫描可能同样快速。如果表有几千个记录,请考虑复合索引。< /P> 要求计数而不是字段

如果要从选择ukey、uid切换。。。要选择count*,从数据库返回的数据将是单个数字。应用程序和数据库之间的比特数将减少,吞吐量将提高。我不知道这种改善是否会显著,除非它正在大规模运行

这可能有一个与PHP相关的好处。您可以使用$count=$sql->fetchColumn直接在变量中获取计数,而不是$result=$sql->fetchAll。如果$count>0,PHP可以更快地进行比较

哪里有

可以替换为以下内容:

WHERE EXISTS (
   SELECT 1 FROM `Token`
   WHERE ukey = :ukey AND uid = :uid AND timeexp >= now())
)
这样,就不需要计数*并将其与1进行比较


您已经做了一项很好的工作,定期清除信息,以保持一个小而干净的数据集。这将有助于查询和缩放。

在ukey和uid上有复合索引吗?给定ukey+uid组合的最大记录数是多少?不要选择uid,ukey,只需请求select count*。然后,使用$result=$sql->fetchColumn;。现在,您的if语句可以像这样进行数字比较:if$result>0{…}。此时没有复合索引,因为表只有4列宽,包括自动递增的主键。此查询不可能每次检索一条以上的记录,因为旧的键行在过期后会被清除,或者在插入的位置使用。。。可以重写为存在的位置从令牌中选择1,在其中…找到。token有多少条记录?几百、几千、几百万?如果您有几千个,您将受益于uid+ukey复合索引。几百兆。超过10公里,这个指数肯定会有所帮助。您正在使用该组合来搜索select和insert…select。酷,扫描50-100行会很快。所以,我只想到了两个要点——where exists和选择count*with fetchColumn
WHERE EXISTS (
   SELECT 1 FROM `Token`
   WHERE ukey = :ukey AND uid = :uid AND timeexp >= now())
)