【问题标题】:Is it possible to do count(*) while doing insert...select... query in mysql/php?在 mysql/php 中执行 insert...select... 查询时是否可以执行 count(*)?
【发布时间】:2010-09-24 19:14:25
【问题描述】:

是否可以在一个 PHP 脚本中执行一个简单的 count(*) 查询,而另一个 PHP 脚本正在执行 insert...select... 查询?

情况是我需要从另一个表中创建一个大约 1M 或更多行的表,并且在插入时,我不希望用户觉得页面冻结,所以我试图继续更新计数,但是在插入背景时使用select count(\*) from table,在插入完成之前我只得到0。

那么有没有办法让 MySQL 先返回部分结果呢?或者是否有一种快速的方法可以使用从先前的选择查询中获取的数据进行一系列插入,同时具有与插入...选择...查询相同的性能?

环境为php4.3和MySQL4.1。

【问题讨论】:

    标签: php mysql insert


    【解决方案1】:

    在提交之前,其他用户无法看到插入。这通常是一件好事,因为它确保他们看不到半完成的数据。但是,如果您希望他们看到中间数据,您可以在插入时偶尔调用“commit”。

    顺便说一句 - 不要让任何人告诉你打开自动提交。这是一个巨大的时间浪费。我的数据库上有一个“删除并重新插入”作业,当我关闭自动提交时,它需要 1/3 的时间。

    【讨论】:

      【解决方案2】:

      不降低性能?不见得。有一点性能损失,也许......

      但是你为什么要定期创建表格并插入数百万行?如果您很少这样做,您不能只是警告管理员(大概是唯一允许这样做的人)这需要很长时间。如果你一直这样做,你真的确定你没有这样做吗?

      【讨论】:

        【解决方案3】:

        需要明确的是,默认情况下 MySQL 4 未配置为使用事务。如果我没记错的话,它使用 MyISAM 表类型,每次插入都会锁定整个表。

        最好的办法是使用 MySQL 批量插入函数之一,例如 LOAD DATA INFILE,因为这些函数在插入大量数据时要快得多。至于计数,你可以将插入分成 N 组,每组 1000 个(或 Y),然后将进度表分成 N 个部分,并根据每个组的请求进行更新。

        编辑: 另一件要考虑的事情是,如果这是模板的静态数据,那么您可以使用“select into”来创建一个具有相同数据的新表。不确定您的应用程序是什么或预期的功能,但也可以。

        【讨论】:

        • LOAD DATA INFILE 从文件中获取数据,而不是像 OP 那样从另一个表中获取数据。必须先将该 SELECT 的结果复制到一个临时文件中,然后才能加载它。这可能对当前解决方案没有任何改进。
        • 对,非常对。我认为我们需要 OP 提供有关用例的更多信息。但是,使用 select x into tablename 可能会有一些用处。这完全取决于最终目标是什么。
        【解决方案4】:

        如果您正在执行单个 INSERT...SELECT,那么不,您将无法获得中间结果。事实上,这将是一件坏事,因为用户永远不会看到处于中间状态的数据库只显示语句或事务的部分结果。如需更多信息,请阅读ACID 合规性。

        也就是说,MyISAM 引擎在这方面可能会玩得又快又松。我很确定我已经看到 MyISAM 提交了一些但不是所有来自 INSERT...SELECT 的行,当我在中途中止它时。不过,您还没有说您的表使用的是哪个引擎。

        【讨论】:

          【解决方案5】:

          我同意 Stein 的评论,即如果您在 PHP 请求期间一次复制 100 万行,这是一个危险信号。

          我相信,在大多数情况下,人们试图对 SQL 进行微优化,通过以不同的方式解决问题,他们可以获得更高的性能和吞吐量。 SQL 不应成为您的瓶颈。

          【讨论】:

            【解决方案6】:

            如果您可以访问控制台,您可以询问各种状态问题,这些问题将为您提供您正在寻找的信息。有一个类似于“SHOW processlist”的命令。

            【讨论】:

              猜你喜欢
              • 2011-08-25
              • 1970-01-01
              • 1970-01-01
              • 2014-08-08
              • 2014-03-04
              • 2014-07-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多