2015-12-18 5 views
1

У меня возникла проблема с кодом SQL. Мы разработали приложение, которое работает на MySQL, и там оно работает нормально. Поэтому я решил дать MariaDB попробовать и установить его на dev-машине. По определенному запросу Stmt у меня проблема с производительностью, которую я не понимаю. Запрос следующим образом:Проблема с производительностью MariaDB с предложением «Where IN»

SELECT SAMPLES.*, UNIX_TIMESTAMP(SAMPLES.SAMPLE_DATE) as TIMESTAMP,RAWS.VALUE, DATAKEYS.RAW_ID, DATAKEYS.DATA_KEY_VALUE, DATAKEYS.DATA_KEY_ID, KEYDEF.KEY_NAME, KEYDEF.LDD_ID 
FROM 
PDS.TABLE_SAMPLES SAMPLES 
RIGHT OUTER JOIN PDS.TABLE_RAW_VALUES RAWS ON SAMPLES.SAMPLE_ID = RAWS.SAMPLE_ID 
RIGHT OUTER JOIN PDS.TABLE_SAMPLE_DATA_KEYS DATAKEYS ON(DATAKEYS.RAW_ID = RAWS.RAW_ID AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) OR 
(DATAKEYS.RAW_ID = 0 AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) 
RIGHT OUTER JOIN PDS.TABLE_DATA_KEY_DEFINITION KEYDEF ON(DATAKEYS.DATA_KEY_ID = KEYDEF.DATA_KEY_ID) 
WHERE 
SAMPLES.SAMPLE_ID IN(1991331,1991637,1991941,2046105,2046411,2046717,2047023,2047635,2047941,2048247) 
AND (SAMPLES.PARAMETER_ID = 9) 
GROUP BY DATAKEYS.DATA_KEY_ID, RAWS.RAW_ID, DATAKEYS.DATA_KEY_ID 
ORDER BY SAMPLES.SAMPLE_ID, DATAKEYS.RAW_ID; 

Пока я получил только одно значение в состоянии «WHERE IN», запрос занимает ~ 10ms для выполнения. Это примерно то же самое, что и MySQL 5.6. Как только я добавляю там еще одно значение, время запроса увеличивается до нескольких минут. В MySQL это происходит очень медленно, Query, показанный вверху, занимает ~ 150 мс в MySQL и около 140 секунд на новой установке MariaDB, используя точно такие же наборы данных.

Я не эксперт по SQL, можете ли вы дать мне несколько подсказок, как оптимизировать запрос для запуска, как ожидалось?

+0

Является ли sample.sample_id индексированным столбцом? – gabe3886

+0

Просто замечание, 'right external join' здесь не имеет смысла, если вы используете' sample_id' в предложении 'where', лучше измените все на' inner join' –

+0

. В чем смысл '' SAMPLES. * 'В вашем выборе вы не группируете ни один из них –

ответ

1

right outer join s преобразуются во внутренние соединения в соответствии с пунктом where. Таким образом, просто используйте правильный join типа (я не уверен, если это влияет на оптимизацию запроса, но он мог):

SELECT SAMPLES.*, UNIX_TIMESTAMP(SAMPLES.SAMPLE_DATE) as TIMESTAMP,RAWS.VALUE, DATAKEYS.RAW_ID, DATAKEYS.DATA_KEY_VALUE, DATAKEYS.DATA_KEY_ID, KEYDEF.KEY_NAME, KEYDEF.LDD_ID 
FROM PDS.TABLE_SAMPLES SAMPLES JOIN 
    PDS.TABLE_RAW_VALUES RAWS 
    ON SAMPLES.SAMPLE_ID = RAWS.SAMPLE_ID JOIN 
    PDS.TABLE_SAMPLE_DATA_KEYS DATAKEYS 
    ON (DATAKEYS.RAW_ID = RAWS.RAW_ID AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) OR 
     (DATAKEYS.RAW_ID = 0 AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) JOIN 
    PDS.TABLE_DATA_KEY_DEFINITION KEYDEF 
    ON DATAKEYS.DATA_KEY_ID = KEYDEF.DATA_KEY_ID) 
WHERE SAMPLES.SAMPLE_ID IN (1991331, 1991637, 1991941, 2046105, 2046411, 2046717, 2047023, 2047635, 2047941, 2048247) AND 
     (SAMPLES.PARAMETER_ID = 9) 
GROUP BY DATAKEYS.DATA_KEY_ID, RAWS.RAW_ID, DATAKEYS.DATA_KEY_ID 
ORDER BY SAMPLES.SAMPLE_ID, DATAKEYS.RAW_ID; 

Далее, лучший показатель для этого запроса - независимо от количества значениями в IN является составной индекс PDS.TABLE_SAMPLES(PARAMETER_ID, SAMPLE_ID). Это обрабатывает предложение WHERE.

Поскольку ваш запрос выполняется быстро при определенных обстоятельствах, я полагаю, что в других таблицах есть соответствующие индексы для объединений.

+0

Индексы, где верно, PDS.TABLE_SAMPLES (PARAMETER_ID, SAMPLE_ID) является первичным ключом для этой таблицы. Однако проблема была связана с неправильными типами соединений. При использовании внутреннего соединения проблема исчезла. Благодаря! –

0

Вместо оператора 'IN' попробуйте использовать 'exists' и используйте подзапрос вместо использования sample_id.

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