【问题标题】:Efficient way to check for the existence of a single MySQL record?检查单个 MySQL 记录是否存在的有效方法?
【发布时间】:2012-01-20 20:25:07
【问题描述】:

需要根据 db 中是否存在一条记录来执行一些逻辑。由于这个函数会经常被调用,我想知道以下是否可以提高效率......

还要注意,该表是一个关联表(employee_id 和 department_id 共同构成一个复合主键),因此只有一条记录符合条件。

例如:

<?php

    function checkEmpDptAssoc($employee_id, $department_id)
    {
        $sqlQuery = sprintf("SELECT COUNT(*)
                             FROM  employee_department ed
                             WHERE ed.employee_id = '%d'
                             AND   ed.department_id = '%d'",
                             $employee_id,
                             $department_id);

        $result = mysql_query($sqlQuery);
        $row = mysql_fetch_assoc($result);

        if ((int) $row['COUNT(*)'] > 0) {
            return true;
        } else {
            return false;    
        } 

    }
?> 

【问题讨论】:

  • 除了下面的答案之外,请确保索引设置正确并适当地重新索引。

标签: php mysql performance


【解决方案1】:

也许你可以试试:

"SELECT ed.employee_id
 FROM  employee_department ed
 WHERE ed.employee_id = '%d'
 AND   ed.department_id = '%d'
 LIMIT 1"

既然您只需要检查是否存在单个记录,那么也许:

if (!empty($row)) {
    return TRUE;
} else {
    return FALSE;
}

[编辑:基于@ColShrapnel 的评论,我遗憾地忘记了]

# instead of above if...else condition:
return empty($row);

对不起,我现在没有时间测试这个,但我能说的是,如果你想提高性能(抛开count() vs limit),先看看你能不能在 where 子句中为一列或两列添加索引,即 employee_iddepartment_id.. 如果 employee_id 应该是唯一的,则将其设为唯一索引,例如:

-- non unique    
create index idx_employeeid on table(employee_department)

-- unique
create unique index idx_employeeid_unq on table(employee_department)

【讨论】:

  • 认为这会比计数更快吗?
  • @eysikal,我很抱歉,在这种情况下,我无法测试limitcount 之间的速度比较......也许这里其他更有经验的人能够告诉你......
  • 实际上,这两个字段共同构成了一个复合主键——这是一个关联表。
  • 看到您的编辑.. 如果只有一条记录.. 那么您可以使用 EXPLAIN 命令查看结果,尝试使用count ,然后是limit,然后没有任何一个,只有SELECT ed.employee_id...
  • 仅供参考:empty($row) 已经返回一个布尔值。
【解决方案2】:

what I am always talking about的完美例子

一个问题,绝对是凭空问出来的。
除了真正重要的事情之外,还有几个答案。
和一个可怜的单独评论,这个问题的唯一明智的答案。

您真正需要关心的唯一一件事是正确的索引
你剩下的问题,所有这些语法问题,运行相同查询的各种变体都没有。

我能想到的唯一改进就是去掉不必要的代码。
选择 1 而不是 count(*) 然后就可以了

    return (bool)mysql_fetch_assoc($result);

它不会影响代码的性能,但会稍微影响编码器的性能。

【讨论】:

  • 我正准备接受这个作为最佳答案,但您包含的代码位将无法正常工作。
  • 如果有结果,则不会评估为真。假的很好。
【解决方案3】:

EXISTS 可能会快一点,因为您只需要确保一个存在即可。

SELECT 1 FROM DUAL
WHERE EXISTS (
    SELECT *
    FROM  employee_department ed
    WHERE ed.employee_id = '%d'
        AND   ed.department_id = '%d'
)

【讨论】:

  • 双重?那是 Oracle 的东西吗?
  • @eysikal 在 MySQL 中受支持,但您可以忽略它。
  • @eysikal 你学到了什么?如何更难地运行简单查询?
  • +1 - 关于 Exists 的优点,对于 linq,我使用了 Any,但想法是一样的。
猜你喜欢
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 2014-10-08
  • 2017-05-26
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多