Я использую MySQL 5.1 на машине Windows Server 2008 R2 с 8 ГБ ОЗУ.
Еженедельно обновляю 2 базы. Обе базы данных состоят из таблиц MyISAM, и я запускаю сценарий, который выполняет необходимые операции INSERT (без UPDATE / DELETE) в некоторые таблицы (таблица gp ниже содержит более 370 000 000 строк).
В какой-то момент во время выполнения скрипта mysql (весь процесс занимает около 2,5 часов) я вижу, что операторы SELECT, которые выполняются одновременно с INSERT (НО в разных таблицах и даже в разных базах данных), «заблокированы» и просто повесить, пока не завершится ВСЕ процесс вставки.
Одна вставка вставит около 50-60 пар целых чисел в таблицу gp, и это может занять до 2-4 секунд (весь процесс будет иметь около 2000-4000 пар каждого из них). Итак, если во время INSERT выполняется 10 SELECT, все они ставятся в очередь, как показано в SHOW PROCESSLIST ниже.
Id User Host db Command Time State Info
35 root localhost:36954 db Query 1 update INSERT INTO db_2.gp VALUES(@g,669313116),(@g,...),... (@g is an integer variable and there would normally be about 50-60 pairs of values here)
42 root localhost:38019 db Query 113 Sending data SELECT * FROM db.g WHERE ...
Этот SHOW PROCESSLIST был запущен при локальном тестовом запуске сценария, но такое же поведение можно заметить на LIVE-сервере, когда он обновляется. Я не знаю, почему SELECT блокируются (выше есть только 1 SELECT, поскольку он исходил из localhost, но на LIVE-сервере может быть много разных SELECT, поставленных в очередь из запросов пользователей).
В приведенном выше списке процессов можно увидеть, что INSERT выполняется для таблицы gp в базе данных db_2, в то время как оператор SELECT выполняется для таблицы g в базе данных db. Итак, это разные таблицы (и в разных базах данных), поэтому я не понимаю, почему здесь возникает проблема с блокировкой.
Есть ли способ заставить INSERT не блокировать SELECT? Пожалуйста, не говорите мне использовать вместо этого InnoDB, поскольку я пробовал это, и сайт значительно замедлился. Мне нужно продолжать использовать MyISAM.
В INSERT
не "блокирует" SELECT
в приведенном вами примере списка процессов. Почти наверняка происходит то, что INSERT
берет целую кучу операций ввода-вывода, истощая SELECT
обращений к диску необходимо завершить отправку данных клиенту.