2012-04-24 2 views
1

У меня небольшая проблема; У меня есть 2 стола: events и multimedia. events имеетИсключить запрос sql очень медленно

id, 
device_id 
created_at field 

первичный ключ является идентификатором и есть индекс, образованный device_id и created_at поля.

multimedia таблица имеет поле следящее:

id 
device_id 
created_at 
data (this field is a blob field and contains a 20k string) 

первичный ключ является идентификатором, а есть индекс, образованный device_id и created_by поля.

Проблема в том, когда я хочу удалить запись с created_at перед данными.

запрос:

DELETE FROM events WHERE device_id = #{dev[0]} 
AND created_at <= '#{mm_critical_time.to_s}' 

нормально. За 5 или 6 секунд delete запись.

Запрос

DELETE FROM multimedia WHERE device_id = #{dev[0]} 
AND created_at <= '#{mm_critical_time.to_s}' 

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

В чем проблема?

ответ

2

Возможно, вам необходимо создать индекс для столбцов, которые вы ищете.

CREATE INDEX device_created_index 
ON multimedia (device_id, created_at); 

Если вы хотите узнать больше об оптимизации запросов, обратитесь к ответу я дал здесь об использовании EXPLAIN SELECT: is there better way to do these mysql queries?

+0

я уже создать этот индекс – Dabidi

+0

Тогда я предлагаю вам EXPLAIN ваших запросов, как указано в ответе, я связан с. –

0

порядок условий является важным, вы havent't сказали нам ваши сервер баз данных, но по крайней мере, в Oracle это, поэтому постарайтесь обратить их как

DELETE FROM multimedia WHERE 
created_at <= '#{mm_critical_time.to_s}' 
AND device_id = #{dev[0]} 

или нам внутренний запрос на самой быстрой части

DELETE FROM multimedia WHERE 
created_at <= '#{mm_critical_time.to_s}' 
AND device_id in (select device_id from multimedia where device_id = #{dev[0]}) 

Кроме того, я всегда прерываю медленные запросы и проверяю детали на скорости, чтобы вы знали, где узкое место. Некоторые программы показывают, как долго выполнялся запрос, а в Ruby вы можете использовать бенчмарк, вы можете дополнить удаление с помощью выбора во время тестирования.

так тест:

select * FROM multimedia WHERE created_at <= '#{mm_critical_time.to_s}' 

и

select * from multimedia WHERE device_id = #{dev[0]} 

Success ..

0

Это довольно наивное, чтобы дать решение проблем производительности в реляционных базах данных, не зная всей истории, так как имеется много переменных.

Для данных вы предоставили, хотя, я хотел бы предложить вам отказаться от первичных ключей и индексов и запуска:

CREATE UNIQUE CLUSTERED INDEX uc ON events (device_id, created_at); 
CREATE UNIQUE CLUSTERED INDEX uc ON multimedia (device_id, created_at); 

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

CREATE UNIQUE INDEX ix_id ON events (id); 
CREATE UNIQUE INDEX ix_id ON multimedia (id); 
Смежные вопросы