0

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

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

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

环境为php4.3和MySQL4.1。

4

6 回答 6

3

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

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

于 2008-12-01T17:58:33.060 回答
2

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

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

于 2008-12-01T18:06:29.190 回答
0

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

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

于 2008-12-01T17:55:58.290 回答
0

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

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

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

于 2008-12-01T18:01:05.627 回答
0

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

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

于 2008-12-01T18:01:26.097 回答
0

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

于 2008-12-01T18:07:59.700 回答