2012-06-20 4 views
0

У меня есть таблица с 300 000 записей (MyISAM). Я получаю запись из таблицы с помощью этой функции:Оптимизировать запрос mysql (SELECT)?

public function loadRows() { 
    if (!$this->result) 
     die("Nothing found!"); 
    $this->rows = array(); 
    while ($r = mysql_fetch_array($this->result, MYSQL_ASSOC)) 
     $this->rows[] = $r; 
    //mysql_free_result($this->result); 
    return $this->rows; 
} 

время оценки для показа 100 записей из этой таблицы составляет 6 секунд, очень медленно и память, из этого запроса составляет 512 МБ. Где я ошибаюсь?

Этот запрос:

SELECT i.* FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id) 
LEFT JOIN (inv_f iff) ON (iff.num = i.num) 
LEFT JOIN (temp_a ta) ON (ta.num = i.num) 
WHERE i.vid = 1 
AND iff.num IS NULL 
AND ta.num IS NULL 
LIMIT 100 

Для i.vid я показать все записи.

Заявленные ИНДЕКС:

i.m_id ИНДЕКС

im.id ПЕРВИЧНЫЙ КЛЮЧ

iff.num ИНДЕКС

i.num ИНДЕКС

ta.num INDEX

Explain, РЕЗУЛЬТАТ

id select_type table type  possible_keys key  key_len ref     rows Extra 
1 SIMPLE  i  ref  vid   vid  4  const    85343 Using where 
1 SIMPLE  im  eq_ref PRIMARY  PRIMARY 4  checksys_r1.i.m_id 1 
1 SIMPLE  iff ref  num   num  182  checksys_r1.i.num 1  Using where 
1 SIMPLE  ta  ref  num   num  194  checksys_r1.i.num 1  Using where 
+1

Вы указали какой-либо индекс? – DonCallisto

+0

Вы присоединяетесь к четырем столам, но говорите только об одном. Опубликуйте более подробную информацию о своей схеме. – lanzz

+0

Являются ли поля 'num' индексированными? – raina77ow

ответ

1

Старт с хода:

EXPLAIN SELECT i.* FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id) 
LEFT JOIN (inv_f iff) ON (iff.num = i.num) 
LEFT JOIN (temp_a ta) ON (ta.num = i.num) 
WHERE i.vid = 1 
AND iff.num IS NULL 
AND ta.num IS NULL 
LIMIT 100 

взгляд на вещи, как полное сканирование строки, файл ввода/вывода и т.д. Сообщение результаты здесь. Иногда может потребоваться ремонт таблицы.

Кроме того, есть ли причина, по которой вы используете MyISAM над InnoDB?

+0

Я опубликовал результат EXPLAIN – dido

+0

таблицы inv, ivm_m - myIsam, но таблица temp_a - innoDB – dido

+0

Если вы выберете i.vid = 1 (пока), выполняется ли запрос быстрее? – StackOverflowed

-1

Есть 2 возможные причины, как, вероятно, способствующими. Во-первых, старайтесь избегать выбора * везде, где это возможно. Явное указание столбцов будет сохранять вас в каждом запросе на присоединение к основной базе данных для повторного поиска имен столбцов. Во-вторых, вы указываете предложение where, которое будет работать только после ваших объединений. Таким образом, он собирается создать массивный набор записей со всеми вашими соединениями, а затем фильтровать эту запись позже. Перемещение вашего условия на само соединение должно повысить производительность. Так .....

SELECT i.Column1, i.Column2, i.Column3 
FROM inv i 
LEFT JOIN (inv_m im) ON (i.m_id = im.id AND i.vid = 1) 
LEFT JOIN (inv_f iff) ON (iff.num = i.num AND iff.num IS NULL) 
LEFT JOIN (temp_a ta) ON (ta.num = i.num AND ta.num IS NULL) 
LIMIT 100 
Смежные вопросы