Оптимизация запросов MySQL для больших таблиц - PullRequest
0 голосов
/ 05 января 2012

У меня очень большая база данных изображений, и мне нужно запустить обновление, чтобы увеличить количество просмотров изображений. Каждый час обновляется более миллиона уникальных строк. Сейчас для выполнения этого запроса требуется около часа. Есть ли способ запустить этот запрос быстрее?

Я создаю таблицу памяти:

CREATE TABLE IF NOT EXISTS tmp_views_table (
    key VARCHAR(7) NOT NULL,
    views INT NOT NULL,
    primary key ( `key` )
) ENGINE = MEMORY

Затем я вставляю 1000 представлений одновременно, используя цикл, который выполняется, пока все представления не будут вставлены в таблицу памяти:

insert low_priority into tmp_views_table 
values ('key', 'count'),('key', 'count'),('key', 'count'), etc...

Затем я запускаю обновление для фактической таблицы следующим образом:

update images, tmp_views_table 
set images.views = images.views+tmp_views_table.views 
where images.key = tmp_views_table.key

это последнее обновление занимает около часа, таблица памяти работает довольно быстро.

Есть ли более быстрый способ сделать это обновление?

1 Ответ

1 голос
/ 10 января 2012

Вы используете Innodb, верно? Попробуйте выполнить общую настройку движка mysql и innodb, чтобы ускорить изменение данных.

Полагаю, у вас есть индекс в поле key таблицы images. Вы можете попробовать запрос на обновление также без индекса для таблицы памяти - в этом случае оптимизатор запросов должен выбрать полное сканирование таблицы памяти.

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

Вот что я использовал в одном проекте, чтобы сделать нечто похожее: вставлять / обновлять данные в реальном времени во временную таблицу и объединять их в объединяющую таблицу один раз в день, так что можете попробовать, если она будет выполняться быстрее.

INSERT INTO st_views_agg (pageid,pagetype,day,count)
  SELECT pageid,pagetype,DATE(`when`) AS day, COUNT(*) AS count FROM st_views_pending WHERE (pagetype=4) GROUP BY pageid,pagetype,day
  ON DUPLICATE KEY UPDATE count=count+VALUES(count);
...