简体   繁体   English

在MySQL / PHP中执行插入…选择…查询时是否可以做count(*)?

[英]Is it possible to do count(*) while doing insert…select… query in mysql/php?

Is it possible to do a simple count(*) query in a PHP script while another PHP script is doing insert...select... query? 当另一个PHP脚本正在执行insert ... select ...查询时,是否可以在一个PHP脚本中进行简单的count(*)查询?

The situation is that I need to create a table with ~1M or more rows from another table, and while inserting, I do not want the user feel the page is freezing, so I am trying to keep update the counting, but by using a select count(\\*) from table when background in inserting, I got only 0 until the insert is completed. 情况是,我需要创建一个表,该表的另一个表中有〜1M或更多行,并且在插入时,我不希望用户感到页面冻结,因此我尝试保持更新计数,但是使用了在插入背景时select count(\\*) from table直到插入完成,我只有0。

So is there any way to ask MySQL returns partial result first? 那么有什么方法可以要求MySQL首先返回部分结果吗? Or is there a fast way to do a series of insert with data fetched from a previous select query while having about the same performance as insert...select... query? 还是有一种快速的方法来执行一系列插入操作,这些插入操作是从先前的选择查询中获取的数据,同时具有与插入...选择...查询相同的性能?

The environment is php4.3 and MySQL4.1. 环境是php4.3和MySQL4.1。

Without reducing performance? 不降低性能? Not likely. 不见得。 With a little performance loss, maybe... 稍有性能损失,也许...

But why are you regularily creating tables and inserting millions of row? 但是,为什么要定期创建表并插入数百万行呢? If you do this only very seldom, can't you just warn the admin (presumably the only one allowed to do such a thing) that this takes a long time. 如果您很少这样做,就不能警告管理员(大概是唯一允许这样做的人),这会花费很长时间。 If you're doing this all the time , are you really sure you're not doing it wrong ? 如果你正在做这一切的时候 ,你真的确定你不是做错了

I agree with Stein's comment that this is a red flag if you're copying 1 million rows at a time during a PHP request. 我同意Stein的评论,如果在PHP请求期间一次要复制100万行,这是一个危险信号。

I believe that in a majority of cases where people are trying to micro-optimize SQL, they could get much greater performance and throughput by approaching the problem in a different way. 我相信,在大多数人试图对SQL进行微优化的情况下,通过以不同的方式解决问题,他们可以获得更高的性能和吞吐量。 SQL shouldn't be your bottleneck. SQL不应成为您的瓶颈。

The other users can't see the insertion until it's committed. 其他用户在提交之前看不到插入。 That's normally a good thing, since it makes sure they can't see half-done data. 这通常是一件好事,因为它可以确保他们看不到半完成的数据。 However, if you want them to see intermediate data, you could throw in an occassional call to "commit" while you're inserting. 但是,如果希望他们看到中间数据,则可以在插入时偶尔调用“提交”。

By the way - don't let anybody tell you to turn autocommit on. 顺便说一句-不要让任何人告诉您开启自动提交功能。 That a HUGE time waster. 那真是浪费时间。 I have a "delete and re-insert" job on my database that takes 1/3rd as long when I turn off autocommit. 我的数据库上有一个“删除并重新插入”作业,当我关闭自动提交功能时,它需要1/3的时间。

Just to be clear, MySQL 4 isn't configured by default to use transactions. 需要明确的是,默认情况下,MySQL 4未配置为使用事务。 It uses the MyISAM table type which locks the entire table for each insert, if I remember correctly. 如果我没记错的话,它使用MyISAM表类型,该类型将为每个插入锁定整个表。

Your best bet would be to use one of the MySQL bulk insertion functions, such as LOAD DATA INFILE , as these are dramatically faster at inserting large amounts of data. 最好的选择是使用MySQL批量插入函数之一,例如LOAD DATA INFILE ,因为这些函数在插入大量数据时会大大加快。 As for the counting, well, you could break the inserts into N groups of 1000 (or Y) then divide your progress meter into N sections and just update it on each group's request. 至于计数,您可以将插入内容分成N组,每组1000个(或Y个),然后将进度表分为N个部分,并根据每个组的请求进行更新。

Edit: Another thing to consider is, if this is static data for a template, then you could use a "select into" to create a new table with the same data. 编辑:要考虑的另一件事是,如果这是模板的静态数据,则可以使用“选择为”来创建具有相同数据的新表。 Not sure what your application is, or the intended functionality, but that could work as well. 不确定您的应用程序是什么,或预期的功能,但是也可以正常工作。

If you're doing a single INSERT...SELECT, then no, you won't be able to get intermediate results. 如果您要执行单个INSERT ... SELECT,则不能,您将无法获得中间结果。 In fact this would be a Bad Thing, as users should never see a database in an intermediate state showing only a partial result of a statement or transaction. 实际上,这将是一件坏事,因为用户永远都不会看到处于中间状态的数据库,该数据库仅显示语句或事务的部分结果。 For more information, read up on ACID compliance. 有关更多信息,请阅读ACID合规性。

That said, the MyISAM engine may play fast and loose with this. 就是说,MyISAM引擎可能与此同时玩得很快。 I'm pretty sure I've seen MyISAM commit some but not all of the rows from an INSERT...SELECT when I've aborted it part of the way through. 我很确定我在部分途中中止MyISAM时会提交一些但不是所有来自INSERT ... SELECT的行。 You haven't said which engine your table is using, though. 不过,您还没有说表正在使用哪个引擎。

If you can get to the console, you can ask various status questions that will give you the information you are looking for. 如果可以进入控制台,则可以提出各种状态问题,这些问题将为您提供所需的信息。 There's a command that goes something like "SHOW processlist". 有一个类似“ SHOW processlist”的命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM