SQL性能 - SELECT COUNT vs SELECT id with LIMIT 1

3

我是一名有用的助手,可以为您翻译相关的 IT 技术内容。您需要翻译的内容如下:

我拥有一个使用 InnoDB 存储引擎的 MySQL 数据库,并希望找到最快的方法来检查一行是否存在。

那么,以下哪种方法更快呢:

    $sql5 = "SELECT id, value FROM pc_taxes WHERE id = :taxId AND client_id = :clientID LIMIT 1";
            $stmt5 = getaccessdata::getInstance()->prepare($sql5);
            $stmt5->bindValue(':clientID', $client_id, PDO::PARAM_INT);
            $stmt5->bindValue(':taxId', $taxID, PDO::PARAM_INT);

            try {
                $stmt5->execute();
                $req5 = $stmt5->fetchAll(PDO::FETCH_ASSOC);
                $countTaxVal = 0;
                foreach ($req5 as $r5) {
                    $countTaxVal++;
                }
            } catch (Exception $e) {

            }

if($countTaxVal>0){
$rowExist=true;
}

或者这个版本在处理非常大的记录时更快:

$sql5 = "SELECT COUNT(*) FROM pc_taxes WHERE id = :taxId AND client_id = :clientID LIMIT 1";
            $stmt5 = getaccessdata::getInstance()->prepare($sql5);
            $stmt5->bindValue(':clientID', $client_id, PDO::PARAM_INT);
            $stmt5->bindValue(':taxId', $taxID, PDO::PARAM_INT);

numRows =0;
            try {
                $stmt5->execute();
                $numRows = $stmt5->fetchColumn();


            } catch (Exception $e) {

            }

if($numRows >0){
$rowExist=true;
}

感谢您的建议。

我已经搜索过了,但从未找到带有LIMIT 1的SELECT COUNT... - Janine Kroser
1
带有限制的计数并没有太多意义... - Neville Kuyt
你以为如果找到一行就会停止计数吗?所以它会计算所有记录,只输出一个? - Janine Kroser
1个回答

3

这不是很重要。

请勿突然提出与性能相关的问题。如果您手头没有问题,请只关注解决方案。

对于您提出的问题,检查行是否存在的最快方法是为涉及查询的列建立索引。这是正确的答案,也是您需要完成任务所需的一切。具体的 SQL 语法并不重要。

因此,对于您的问题,您需要像这样的索引:id_client(id,client_id)

——这就是使您的查询更快的原因。

出于常识,我会说,如果您不需要计数,而只需要一个标志,则选择该标志:

$sql = "SELECT 1 FROM pc_taxes WHERE id = ? AND client_id = ? LIMIT 1";
$stmt = getaccessdata::getInstance()->prepare($sql);
$stmt->execute([$client_id,$taxID]);
$rowExist = $stmt->fetchColumn();

切勿将查询包装成空的try catch。这么做你以后会非常后悔。


id是主键,所以我还需要为client_id添加索引吗?你说的“goodness sake”部分是指我应该处理异常吗? - Janine Kroser
如果是主键,那么您不需要额外的索引。而且您也不需要LIMIT。至于异常情况,请让它们自行处理,不要捕获,也不要“处理”。请参考:https://phpdelusions.net/pdo#errors - Your Common Sense
谢谢您的建议,非常有帮助。在您的示例中,如果 $rowExist = 0,则该行不存在,如果 $rowExist = 1,则存在,我是对的吗? - Janine Kroser
是的,你可以直接在条件语句中使用它,例如 if ($rowExist) ... - PHP 会完全理解它。 - Your Common Sense

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接