Можно ли выполнить простой запрос count (*) в сценарии PHP, в то время как другой сценарий PHP выполняет запрос insert ... select ...?
Ситуация заключается в том, что мне нужно создать таблицу с ~ 1 млн или более строк из другой таблицы, и при вставке я не хочу, чтобы пользователь чувствовал, что страница зависает, поэтому я пытаюсь продолжать обновлять подсчет, но с помощью select count(\*) from table при вставке фона я получил только 0 до завершения вставки.
Итак, есть ли способ попросить MySQL сначала вернуть частичный результат? Или есть быстрый способ выполнить серию вставок с данными, полученными из предыдущего запроса выбора, имея примерно такую же производительность, как запрос insert ... select ...?
Среда - php4.3 и MySQL4.1.






Другие пользователи не смогут увидеть вставку, пока она не будет зафиксирована. Обычно это хорошо, так как гарантирует, что они не смогут увидеть незавершенные данные. Однако, если вы хотите, чтобы они видели промежуточные данные, вы можете периодически вызывать «фиксацию» во время вставки.
Кстати - не позволяйте никому говорить вам включать автокоммит. Это ОГРОМНЫЙ расточитель времени. У меня есть задание «удалить и повторно вставить» в мою базу данных, которое занимает 1/3 от времени, когда я выключаю автоматическую фиксацию.
Без снижения производительности? Скорее всего, не. С небольшой потерей производительности, может быть ...
Но почему вы регулярно создаете таблицы и вставляете миллионы строк? Если вы делаете это очень редко, не могли бы вы просто предупредить администратора (предположительно, единственного, кому разрешено это делать), что это займет много времени. Если вы делаете это все время, вы действительно уверены, что не делаете неправильный?
Чтобы было ясно, MySQL 4 по умолчанию не настроен для использования транзакций. Он использует тип таблицы MyISAM, который блокирует всю таблицу для каждой вставки, если я правильно помню.
Лучше всего использовать одну из функций массовой вставки MySQL, например ЗАГРУЗИТЬ ДАННЫЕ В ФАЙЛ, поскольку они значительно быстрее вставляют большие объемы данных. Что касается подсчета, то вы можете разбить вставки на N групп по 1000 (или Y), затем разделить индикатор выполнения на N разделов и просто обновить его по запросу каждой группы.
Редактировать: Еще одна вещь, которую следует учитывать: если это статические данные для шаблона, вы можете использовать «выбрать в» для создания новой таблицы с теми же данными. Не уверен, что это за приложение или какие функции ему нужны, но это тоже может сработать.
Верно, очень верно. Я думаю, нам нужно больше информации от OP относительно варианта использования. Однако использование select x в tablename может быть полезным. Все зависит от конечной цели.
Если вы выполняете один INSERT ... SELECT, то нет, вы не сможете получить промежуточные результаты. На самом деле это было бы плохо, поскольку пользователи никогда не должны видеть базу данных в промежуточном состоянии, показывающую только частичный результат оператора или транзакции. Для получения дополнительной информации прочтите о соответствии КИСЛОТА.
Тем не менее, движок MyISAM может действовать быстро и свободно с этим. Я почти уверен, что видел, как MyISAM фиксировал некоторые, но не все строки из INSERT ... SELECT, когда я частично прервал его. Однако вы не сказали, какой движок использует ваша таблица.
Я согласен с комментарием Штейна о том, что это красный флаг, если вы копируете 1 миллион строк за раз во время запроса PHP.
Я считаю, что в большинстве случаев, когда люди пытаются микрооптимизировать SQL, они могут добиться гораздо большей производительности и пропускной способности, если подойдут к проблеме другим способом. SQL не должен быть вашим узким местом.
Если вы можете добраться до консоли, вы можете задать различные вопросы о статусе, которые предоставят вам информацию, которую вы ищете. Есть команда, которая выглядит примерно так: «ПОКАЗАТЬ список процессов».
LOAD DATA INFILE берет данные из файла, а не SELECT из другой таблицы, как это делает OP. Нужно было бы скопировать результаты этого SELECT во временный файл, прежде чем его можно будет загрузить. Это не может быть улучшением по сравнению с текущим решением.