Можно ли сделать count (*) при выполнении вставки ... выберите ... запрос в MySQL / PHP? - PullRequest
0 голосов
/ 01 декабря 2008

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

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

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

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

Ответы [ 6 ]

3 голосов
/ 01 декабря 2008

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

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

2 голосов
/ 01 декабря 2008

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

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

0 голосов
/ 01 декабря 2008

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

0 голосов
/ 01 декабря 2008

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

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

0 голосов
/ 01 декабря 2008

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

Лучше всего было бы использовать одну из функций массовой вставки MySQL, например, LOAD DATA INFILE , поскольку они значительно ускоряют вставку больших объемов данных. Что касается подсчета, вы можете разбить вставки на N групп по 1000 (или Y), а затем разделить свой индикатор прогресса на N секций и просто обновить его по запросу каждой группы.

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

0 голосов
/ 01 декабря 2008

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

Кстати, не позволяйте никому говорить, чтобы вы включили автокоммит. Это огромная трата времени. У меня есть задание «удалить и вставить заново» в моей базе данных, которое занимает 1/3 времени, когда я выключаю автокоммит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...