Можно ли сделать count (*) при выполнении запроса insert ... select ... в mysql / php?

Можно ли выполнить простой запрос count (*) в сценарии PHP, в то время как другой сценарий PHP выполняет запрос insert ... select ...?

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

Итак, есть ли способ попросить MySQL сначала вернуть частичный результат? Или есть быстрый способ выполнить серию вставок с данными, полученными из предыдущего запроса выбора, имея примерно такую ​​же производительность, как запрос insert ... select ...?

Среда - php4.3 и MySQL4.1.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
2 597
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Другие пользователи не смогут увидеть вставку, пока она не будет зафиксирована. Обычно это хорошо, так как гарантирует, что они не смогут увидеть незавершенные данные. Однако, если вы хотите, чтобы они видели промежуточные данные, вы можете периодически вызывать «фиксацию» во время вставки.

Кстати - не позволяйте никому говорить вам включать автокоммит. Это ОГРОМНЫЙ расточитель времени. У меня есть задание «удалить и повторно вставить» в мою базу данных, которое занимает 1/3 от времени, когда я выключаю автоматическую фиксацию.

Без снижения производительности? Скорее всего, не. С небольшой потерей производительности, может быть ...

Но почему вы регулярно создаете таблицы и вставляете миллионы строк? Если вы делаете это очень редко, не могли бы вы просто предупредить администратора (предположительно, единственного, кому разрешено это делать), что это займет много времени. Если вы делаете это все время, вы действительно уверены, что не делаете неправильный?

Чтобы было ясно, MySQL 4 по умолчанию не настроен для использования транзакций. Он использует тип таблицы MyISAM, который блокирует всю таблицу для каждой вставки, если я правильно помню.

Лучше всего использовать одну из функций массовой вставки MySQL, например ЗАГРУЗИТЬ ДАННЫЕ В ФАЙЛ, поскольку они значительно быстрее вставляют большие объемы данных. Что касается подсчета, то вы можете разбить вставки на N групп по 1000 (или Y), затем разделить индикатор выполнения на N разделов и просто обновить его по запросу каждой группы.

Редактировать: Еще одна вещь, которую следует учитывать: если это статические данные для шаблона, вы можете использовать «выбрать в» для создания новой таблицы с теми же данными. Не уверен, что это за приложение или какие функции ему нужны, но это тоже может сработать.

LOAD DATA INFILE берет данные из файла, а не SELECT из другой таблицы, как это делает OP. Нужно было бы скопировать результаты этого SELECT во временный файл, прежде чем его можно будет загрузить. Это не может быть улучшением по сравнению с текущим решением.

Bill Karwin 01.12.2008 21:05

Верно, очень верно. Я думаю, нам нужно больше информации от OP относительно варианта использования. Однако использование select x в tablename может быть полезным. Все зависит от конечной цели.

willasaywhat 01.12.2008 21:08
Ответ принят как подходящий

Если вы выполняете один INSERT ... SELECT, то нет, вы не сможете получить промежуточные результаты. На самом деле это было бы плохо, поскольку пользователи никогда не должны видеть базу данных в промежуточном состоянии, показывающую только частичный результат оператора или транзакции. Для получения дополнительной информации прочтите о соответствии КИСЛОТА.

Тем не менее, движок MyISAM может действовать быстро и свободно с этим. Я почти уверен, что видел, как MyISAM фиксировал некоторые, но не все строки из INSERT ... SELECT, когда я частично прервал его. Однако вы не сказали, какой движок использует ваша таблица.

Я согласен с комментарием Штейна о том, что это красный флаг, если вы копируете 1 миллион строк за раз во время запроса PHP.

Я считаю, что в большинстве случаев, когда люди пытаются микрооптимизировать SQL, они могут добиться гораздо большей производительности и пропускной способности, если подойдут к проблеме другим способом. SQL не должен быть вашим узким местом.

Если вы можете добраться до консоли, вы можете задать различные вопросы о статусе, которые предоставят вам информацию, которую вы ищете. Есть команда, которая выглядит примерно так: «ПОКАЗАТЬ список процессов».

Другие вопросы по теме