2016-05-30 2 views
0

Мне нужно улучшить этот запрос SQL UPDATE. Запрос должен обновлять только первую строку, но я подозреваю, что он использует большую мощность при работе через все строки и запускает подзапрос для всех строк, потому что при использовании больших баз данных это очень медленно. Какие-либо предложения?Улучшение SQL UPDATE

UPDATE leads l 
    SET status='processing', processor='$processor' 
    WHERE pool IN ($pools) AND status='active' 
    ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC 
    LIMIT 1 

ОБНОВЛЕНИЕ

Медлительность действительно вызвано подвыборки. Типичным может быть 2000-3000 совпадений в таблице. Самый простой способ - построить столбец в таблице lead-table, который подсчитывает вызовы вручную, поэтому мне не нужен подзапрос, но это работающий сайт, на котором эти изменения необходимо сделать, поэтому это испортит порядок, если Я добавил колонку сейчас.

Но я полагаю, что это единственный способ избежать большого подзапроса.

+0

Это звучит, как вы пропустили индекс? Поместите 'EXPLAIN' перед вашим запросом, чтобы увидеть, что он делает ... –

+0

попробовал' EXPLAIN EXTENDED UPDATE ... '? 'EXPLAIN EXTENDED' возвращает некоторую дополнительную информацию о том, что происходит именно при запуске запроса UPDATE. –

ответ

0

Для меня - медлительность исходит из подзадачи. Для каждого pool вы запрашиваете все calls, чтобы рассчитать их количество. Сначала убедитесь, что calls.lead индексируется. Вы можете сохранить этот счетчик в pool и иметь триггеры, чтобы сохранить это реальность. Другим вариантом является сохранение этой информации внутри индекса, но я не могу сказать, как использовать ее в MySQL, особенно в неизвестной версии

+0

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

+0

'пул IN ($ пулы) AND status = 'active'' - для каждого из них вы вызываете' SELECT count (*) FROM calls c WHERE c.lead = l.id' - для сортировки. Сначала убедитесь, что 'c.lead = l.id' использует индекс. Если это все еще слишком медленно - добавьте 'count (*) FROM вызовы c WHERE c.lead = l.id' как отдельный столбец в' pool' и обновите его с помощью триггеров –

0

Создание индекса с несколькими столбцами для таблицы-столбца для столбцов pool и status будет представлять собой самый простой способ ускорить обновление. Но сколько строк действительно в вашем лидирующем столе? И сколько строк соответствует вашему предложению where?

Multiple Index Колонка

ALTER TABLE your_schema.leads 
    ADD INDEX faster_update(pool,status) ; 

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

В случае, если ваш не знаю, если используется индекс, используйте следующий код для анализа запроса:

EXPLAIN EXTENDED SELECT * FROM your_schema.leads 
    WHERE pool IN ($pools) AND status='active' 
    ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC 

Или просто опубликовать результат здесь

Смежные вопросы