【问题标题】:Where should I do the rowcount when checking for existence: sql or php?检查存在时我应该在哪里进行行计数:sql 还是 php?
【发布时间】:2010-09-25 03:41:11
【问题描述】:

在我想检查的情况下,如果数据库中的某个条目存在,我有两个选择。

我可以使用 COUNT() 创建一个 sql 查询,然后检查结果是否 >0...

...或者我可以只检索记录,然后计算返回的行集中的行数。例如 $result->num_rows;

什么更好/更快?在 mysql 中?一般?

【问题讨论】:

  • 如果你用 mysql 标记你的问题可能会很有用。在阅读 cmets 之前不知道这是特定于 mysql 的。
  • 实际上我想知道它的一般性和具体性,因为我不只使用 mysql...我在问题中添加了这个。

标签: sql count


【解决方案1】:

YMMV,但我怀疑如果您只是检查是否存在,并且不需要以任何方式使用检索到的数据,那么 COUNT() 查询会更快。速度快多少取决于数据量。

【讨论】:

    【解决方案2】:

    最快的可能是询问数据库是否存在:

    SELECT EXISTS ([your query here])
    

    【讨论】:

    • 这可以快得多,因为您不在乎多少可以节省 SQL 时间。
    • 它让(数据库服务器)优化器有机会去做它的事情:如果你只需要知道它在那里,就不需要计算东西。
    • 你们都错了,这种方法对于小表来说可能更快,但是一旦超过一定数量的数据,SELECT COUNT() 会更快。如果您必须盲目选择,请选择 COUNT(),因为它在大桌子上也很快,在小桌子上也同样快。
    • 在我的情况下(mysql)我别无选择,因为 EXISTS 似乎只能在子查询中使用
    • 在我看来它确实存在 ;-)。 EXIST 子句当然作用于子查询。见informit.com/articles/article.aspx?p=377653&seqNum=8
    【解决方案3】:
    SELECT 1 
      FROM (SELECT 1) t 
     WHERE EXISTS( SELECT * FROM foo WHERE id = 42 )
    

    刚刚测试,在 MySQL v5 上运行良好

    COUNT(*) 通常在以下情况下效率较低:

    1. 您可以有重复项(因为 DBMS 将不得不详尽无遗 搜索所有记录/索引 给你确切的答案)或
    2. 有 NULL 条目(对于相同的 原因)

    如果您基于 WHERE 子句进行计数,该子句保证生成单个记录(或 0)并且 DBMS 知道这一点(基于 UNIQUE 索引),那么它应该是一样高效。但是,您不太可能总是有这种情况。此外,取决于版本和 DBMS,DBMS 可能并不总是能够接受这一点。

    在应用程序中计数(当您不需要该行时)几乎总是保证会更慢/更差,因为:

    1. 你必须向客户端发送数据,客户端必须对其进行缓冲并做一些工作
    2. 您可能会在 DBMS MRU/LRU 数据缓存中发现更重要的内容
    3. 您的 DBMS(通常)必须执行更多磁盘 I/O 来获取您永远不会使用的记录数据
    4. 您有更多网络活动

    当然,如果你想对存在的行做一些事情,那么简单地尝试获取开始的行肯定更快/最好!

    【讨论】:

    • 如果我想在存在的情况下检索数据,这听起来是最好的选择!谢谢!
    • 您是否介意添加一小段关于仅检查一方面检查和另一方面检查加是否存在检索的区别。那么我会将您的答案标记为已接受。
    【解决方案4】:

    如果你所做的只是检查是否存在,那么

    Select count(*) ...
    

    但是如果你要检索数据,如果它存在,那么只需获取数据并在 PHP 中检查它,否则你将有两个调用。

    【讨论】:

      【解决方案5】:

      对我来说是在数据库中。

      进行 count(1) 比 $result->num_rows 更快,因为在 $result->num_rows 中,您进行 2 次操作 1 选择,如果选择有计数则进行计数更快地获得结果。 除非您还想从数据库中获取信息。

      【讨论】:

        【解决方案6】:

        如果您想要原始速度,请进行基准测试!除了其他人建议的方法:

        SELECT 1 FROM table_name WHERE ... LIMIT 1
        

        由于避免了子选择,可能会更快。对其进行基准测试。

        【讨论】:

          【解决方案7】:
          SELECT COUNT(*) FROM table
          

          是最好的选择,这个操作在小表和大表上都非常快。虽然有可能

          SELECT id FROM table
          

          在小桌子上更快,速度差异将是微观的。但是如果你有一个大表,这个操作可能会很慢。

          因此,总体而言,最好的选择是始终选择COUNT(*) the table(并且选择* 比选择特定的column 更快),这将是最快的操作。

          【讨论】:

          • 现在我们正在讨论数据库实现。 COUNT() 并不总是很快。例如,在 Postgresql 中,非常大的表上的 COUNT() 可能会非常慢。另一方面,EXISTS 就是为此目的而制作的。
          • 只是据我所知,在 mysql 中没有 EXISTS
          • 我会试试的。 (我自己做不到)
          【解决方案8】:

          我肯定会在 PHP 中这样做以减少数据库的负载。

          为了获得计数在 SQL 中获得返回的行,您必须执行两个查询。一个 COUNT,然后是一个 SELECT

          PHP 方式在一个结果对象中为您提供所需的一切。

          【讨论】:

          • 我认为这不会减少数据库的负载。数据库必须实际获取数据,并且必须将其传输并转换为 PHP。相反,当执行 SELECT EXISTS 时,数据库可以只查询它的索引。
          猜你喜欢
          • 1970-01-01
          • 2015-06-12
          • 2014-05-10
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 2012-07-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多