SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 12.03.2011 23:12:10

Me
Участник
Зарегистрирован: 12.03.2011
Сообщений: 2

Помогите пожалуйста оптимизировать очень медленный запрос

Доброго времени суток.

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

Запрос:


SELECT m.prod_id, i.type_id,  
COUNT(DISTINCT i.id) AS count
FROM model_new AS m
JOIN model_specifications_values AS c
ON c.model_id = m.id
AND c.specification_id = 114
JOIN java_platforms_compatibility AS jpc
ON c.value_i = jpc.compatibility
JOIN my_content_item AS i
ON jpc.id = i.platform_id
AND i.is_smartphone = 0
WHERE i.type_id = 1
GROUP BY m.prod_id , i.type_id

UNION ALL

SELECT m.prod_id, i.type_id,  
COUNT(DISTINCT i.id) AS count
FROM model_new AS m
JOIN model_specifications_values AS c
ON c.model_id = m.id
AND c.specification_id = 111
JOIN os_ui_compatibility AS ouc
ON c.value_i = ouc.compatibility
JOIN my_content_item AS i
ON ouc.id = i.os_ui_id
WHERE i.type_id = 1
GROUP BY m.prod_id , i.type_id

UNION ALL

SELECT m.prod_id, i.type_id,  
COUNT(DISTINCT i.id) AS count
FROM model_new AS m
JOIN model_specifications_values AS c
ON c.model_id = m.id
AND c.specification_id = 114
JOIN model_specifications_values AS chs
ON m.id = chs.model_id
AND chs.specification_id = 4
JOIN java_platforms_themes_compatibility AS jptc
ON c.value_i = jptc.compatibility
JOIN my_content_item AS i
ON jptc.id = i.platform_id
AND i.is_smartphone = 0
AND chs.value_s = i.screen_size
WHERE i.type_id = 2
GROUP BY m.prod_id , i.type_id

UNION ALL

SELECT m.prod_id, i.type_id,  
COUNT(DISTINCT i.id) AS count
FROM model_new AS m
JOIN model_specifications_values AS c
ON c.model_id = m.id
AND c.specification_id = 111
JOIN model_specifications_values AS chs
ON m.id = chs.model_id
AND chs.specification_id = 4
JOIN os_ui_compatibility AS ouc
ON c.value_i = ouc.compatibility
JOIN my_content_item AS i
ON ouc.id = i.os_ui_id
AND chs.value_s = i.screen_size
WHERE i.type_id = 2
GROUP BY m.prod_id
 


Результат:

В результате 47 строк.
Запрос занял 95.2452 сек.
Если выполнять запросы по отдельности, то:
1-й запрос выбирает 23 строки (0.7982 сек);
2-й запрос выбирает 17 строк (1.7528 сек);
3-й запрос выбирает 3 строки (8.3147 сек);
4-й запрос выбирает 4 строки (82.6151 сек).

Сам оптимизировать смог только до такого состояния. До этого выполнялось в несколько раз дольше.

EXPLAIN:

id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1    PRIMARY    c    ref    specification_id,model_id,value_i    specification_id    1    const    2968    Using temporary; Using filesort
1    PRIMARY    m    eq_ref    PRIMARY    PRIMARY    2    mobile.c.model_id    1    
1    PRIMARY    i    ALL    type_id,platform_id    NULL    NULL    NULL    11824    Using where; Using join buffer
1    PRIMARY    jpc    eq_ref    PRIMARY,compatibility    PRIMARY    3    mobile.i.platform_id,mobile.c.value_i    1    Using where; Using index
2    UNION    c    ref    specification_id,model_id,value_i    specification_id    1    const    248    Using temporary; Using filesort
2    UNION    ouc    ref    PRIMARY,compatibility    compatibility    1    mobile.c.value_i    2    Using where; Using index
2    UNION    m    eq_ref    PRIMARY    PRIMARY    2    mobile.c.model_id    1    
2    UNION    i    ref    type_id,os_ui_id    os_ui_id    2    mobile.ouc.id    3    Using where
3    UNION    chs    ref    specification_id,model_id    specification_id    1    const    1727    Using temporary; Using filesort
3    UNION    m    eq_ref    PRIMARY    PRIMARY    2    mobile.chs.model_id    1    
3    UNION    c    ref    specification_id,model_id,value_i    model_id    2    mobile.chs.model_id    52    Using where
3    UNION    jptc    ref    PRIMARY,compatibility    PRIMARY    1    mobile.c.value_i    3    Using where; Using index
3    UNION    i    ref    type_id,platform_id    platform_id    2    mobile.jptc.id    591    Using where
4    UNION    c    ref    specification_id,model_id,value_i    specification_id    1    const    248    Using temporary; Using filesort
4    UNION    ouc    ref    PRIMARY,compatibility    compatibility    1    mobile.c.value_i    2    Using where; Using index
4    UNION    m    eq_ref    PRIMARY    PRIMARY    2    mobile.c.model_id    1    
4    UNION    i    ref    type_id,os_ui_id    os_ui_id    2    mobile.ouc.id    3    Using where
4    UNION    chs    ref    specification_id,model_id    model_id    2    mobile.c.model_id    52    Using where
NULL    UNION RESULT    <union1,2,3,4>    ALL    NULL    NULL    NULL    NULL    NULL

Отредактированно Me (12.03.2011 23:16:48)

Неактивен

 

#2 13.03.2011 22:15:36

Lem0nti
Гуру
Откуда: Северная Пальмира
Зарегистрирован: 08.11.2007
Сообщений: 98

Re: Помогите пожалуйста оптимизировать очень медленный запрос

Вот узкое место:
1    PRIMARY    i    ALL    type_id,platform_id    NULL    NULL    NULL    11824    Using where; Using join buffer

Вероятно необходимы ещё индексы по следующим полям для таблицы my_content_item: is_smartphone, type_id.
Также, рекомендую вам условия с константами вынести из условия join в условие where. Для получившейся пары полей также можно сделать двойной индекс: is_smartphone+type_id, причем порядок полей в индексе и в условии должен быть одинаков.

Отредактированно Lem0nti (13.03.2011 22:19:23)

Неактивен

 

#3 14.03.2011 04:13:34

Me
Участник
Зарегистрирован: 12.03.2011
Сообщений: 2

Re: Помогите пожалуйста оптимизировать очень медленный запрос

Благодарю за ответ.

На самом деле узким местом была не выборка 11824 строк из таблицы (оптимизатор намеренно не использовал индекс, т.к. в первом запросе это оказалось действительно быстрее), а объединения типа этого:


JOIN model_specifications_values AS c
ON c.model_id = m.id
AND c.specification_id = 114
 


Помогло создание индекса: specification_id + model_id. А также добавил индекс: platform_id + type_id + is_smartphone.
Время запроса сократилось до 5-7 секунд, что уже более или менее приемлемо.

Неактивен

 

#4 25.03.2011 11:55:28

Евгения09
Участник
Зарегистрирован: 25.03.2011
Сообщений: 2

Re: Помогите пожалуйста оптимизировать очень медленный запрос

Добрый день. Вы бы не могли подсказать как можно оптимизировать следующий запрос:

  SELECT Payment_Current.ID_Payment,
    Payment_Current.Ref_Student,
    Payment_Current.Sum,
    Payment_Current.Sum_USD,
    Payment_Current.PayDate,
    Payment_Current.RegDate,
    Reason.Reason_Name,
    Payment_Form.PaymentForm_Name,
    Bank.Bank_Name,
    Payment_Current.PaymentBasis,
    Payment_Current.Payer,
    Payment_Type.PaymentType_Name,
    Payment_Year.PaymentYear_Name
FROM    Payment_Type RIGHT JOIN (Payment_Year
                RIGHT JOIN(Reason
                RIGHT JOIN (Payment_Form
                RIGHT JOIN (Bank
                RIGHT JOIN Payment_Current
                ON   Bank.ID_Bank=Payment_Current.Ref_Bank)
                ON Payment_Form.ID_PaymentForm=Payment_Current.Ref_PaymentForm)
                ON Reason.ID_Reason=Payment_Current.Ref_Reason)
                ON ref_PaymentYear=id_PaymentYear)
                ON ref_PaymentType=id_PaymentType
В результате 388779 строк. Выполняется 17 сек.

Неактивен

 

#5 25.03.2011 18:18:37

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Помогите пожалуйста оптимизировать очень медленный запрос

Я бы переписал правые вложенные объединения в левые невложенные,
а еще лучше — во внутренние там, где это можно.

И EXPLAIN бы показал после этого. Но, кажется, что при 23 тысячах строк
в секунду Вы упираетесь просто в отдачу строк наружу.

Неактивен

 

#6 26.03.2011 15:55:35

Евгения09
Участник
Зарегистрирован: 25.03.2011
Сообщений: 2

Re: Помогите пожалуйста оптимизировать очень медленный запрос

спасибо за ответ.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson