Имеем БД, innodb конфиг такой Код (Text): [mysqld] federated pid-file = /var/run/mysqld/mysqld.pid datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 max_allowed_packet = 64M thread_cache_size = 8 query_cache_size = 64M query_cache_limit = 16M sort_buffer_size = 8M read_rnd_buffer_size = 16M #thread_concurrency = 8 tmp_table_size = 128M max_heap_table_size = 128M key_buffer_size = 32M table_open_cache = 2048 innodb_buffer_pool_size = 2G innodb_additional_mem_pool_size = 20M innodb_flush_log_at_trx_commit = 2 innodb_thread_concurrency = 16 все вроде чудно, все пашет....НО Есть одна задача, она описана в одной функции, она по кругу вызывает сама себя пока не закончит обрабатывать некую таблицу И есть такая особенность, начинает работать все это за здравие, очень быстро Но по мере выполнения задачи процесс замедляется, т.е. к примеру если вначале 300 строк обрабатывается за 0.5 секунды, то обработав 50 тысяч строк, другие 300 строк обрабатываются уже 5 секунд ((( Может подскажите куда копать? Или мало инфы дал?
нет там смотри, идет выборка из таблицы удовлетворяющая какому то условию в выборке может быть и 1 строка и 1000 далее это 1-1000 строк обрабатываются и распихиваются по другим таблицам далее то что попало под эту выборку удаляется из таблицы и функция вызывает сама себя для следующей итерации
тогда предположу, что следующая итерация в том же процессе: без освобождения памяти, без завершения транзакции. это накладно.
я то же так думал, поэтому перед следующей итерацией удаляю все переменные насчет транзакций после обработки строк из выборки, открывается транзакция, все бухается в 3-4 таблицы, транзакция закрывается, функция вызывает сама себя может как по другому попробовать? я долго колдовал с конфигом, и в какой то момент у меня все работало очень шустро, потом что то еще наколдовал...и опять тупняк по нарастающей (
там может не в конфиге было, а вообще в чём-то ещё. вообще рекурсия с запросами это жестоко, там раз на раз не приходится))
Реально непонятно зачем здесь нужна рекурсия. Почему нельзя заново стартовать скрипт с гарантированно новой средой и новой транзакцией. PHP "рожден чтобы умирать" Не настаиваю, просто я бы сделал ежеминутный крон с проверкой какой-нибудь блокировки на случай если предыдущая итерация еще не закончилась. Добавлено спустя 7 минут 40 секунд: P.S. Понятно, что ты задал вопрос про конфигурацию БД, но кажется она не при чем.
Сегодня я нашел причину тупняка...конфиг да..ваще не при делах. Всякий разный софт для анализа говорил то то увеличить, то это. Проблема была вот в чем: внутри транзакции вставлялись махам много строк, часть сотни, иногда десятки тысяч. А потом, по полю варчхар выбирались некие значения, получаемые путем перебора массива. Ключи у массива как строковые, так могут бытьь и инт. Так вот, запрос инта в поле варчхар занимал 0.1-0.2 секунды!!! А запрос стринга от инта 0.001 сек )))) Жесть...никогда бы не подумал ) Да...вот еще что. Когда в бд было 100-200 тысяч строк, все работало влет. Стало больше ляма....на тебе. Зы сори, с телефона пишу. Убивать совсем не хочу, ибо перед первым запуском идет несколько выборок из бд которые потом как параметры функции передаются. Ну хотя там семечки конечно...пару десятых секунды. Добавлено спустя 8 минут 32 секунды: Да...замедление работы может и есть, но на глаз я его не заметил, завтра понаблюдаю еще
select id from table where field = 123 // 0.1 cek select id from table where field = '123' // 0.001 cek field - столбец VARCHAR 50
5 раз менялась ) это пока оптимальный вариант ) Добавлено спустя 3 минуты 44 секунды: Понимаешь...если бы все зависело только от меня, в этом поле был ты int. Но я не могу заставить сотни магазинов переделать свои бд ((( У них вот так заведено, id товара это А123 В456
а я не про то, что там должен быть инт Инт это скучно. Все теги всегда словами и всегда быстро. Где грабли? =)
Дык я же выше написал ) Они в том, что выбирается значение INT из поля VARCHAR. Как только я сделал string(123) работать стало в 100 раз быстрее )
оно не уникально, но проиндексировано возможно проблема еще в том, что внутри одной транзакции все это происходит, т.е. например одним запросом insert 1000 строк, потом надо взять fields 10 строк из только что вставленных, соответвенно табличка еще не переиндексировалась, может по этому
Думаю здесь не одна заморочка, а две. Они просто присутствуют одновременно. Длинная транзакция сама по себе и смена плана запроса при "неправильных" константах сама по себе. Я на экспериментах с INT вместо CHAR столкнулся с такой штукой в EXPLAIN EXTENDED: В одних случаях он пишет в Extra: А в других случаях в Extra: Почему так: по возможности MySQL сравнивает твои константы из запроса с известным ему набором значений. И в некоторых случаях сразу решает "такого значения нет, запрос можно не выполнять". Как если бы было указано "… WHERE 0" А при других константах ему таки придется сканировать таблицу. Целые-вместо-строк гарантированно не используют const таблицы! Поиграй с EXPLAIN EXTENDED SELECT … и сразу после него попробуй SHOW warnings, бывает любопытно
Тут проблема не в типе константы (при необходимости будет "тихая" конвертация). Смотри план выполнения запроса - возможно в первом случае не используется индекс. Попробуй добавить "use index()" или "force index()", возможно поможет.
Это может быть частный случай. Скорее всего "тупит" оптимизатор. Кто бы спорил. Но иногда оптимизатор тупит и ему надо помочь, поэтому я и написал "возможно поможет".
чувак, проблема только в одном, ты делаешь запрос строки без кавычек. Делай в кавычках, может даже используй сфинкса и будет тебе счастье, выноси старые записи в архив, ограничивай поиск по дате и т.п.