За последние 24 часа нас посетили 32749 программистов и 1820 роботов. Сейчас ищут 945 программистов ...

Помогите оптимизировать запрос

Тема в разделе "MySQL", создана пользователем Denis, 25 сен 2008.

  1. Denis

    Denis Активный пользователь

    С нами с:
    5 фев 2006
    Сообщения:
    92
    Симпатии:
    0
    Адрес:
    Украина, Одесса
    [sql]select pp.*, s.*,
    sg.name as genre_name, sg.alias as genre_alias,
    su.login as author_login,
    (select count(*) from comments where table_id = N and primary_id = s.id and datetime > NOW() - INTERVAL N DAY)+
    (select count(*) from portal_rates where struct_id = s.id and datetime > NOW() - INTERVAL N DAY)+
    (select count(*) from struct_views where struct_id = s.id and datetime > NOW() - INTERVAL N DAY)
    as global_rate
    from portal_pictures pp
    join struct s on pp.struct_id = s.id
    left join struct sg on pp.genre_id = sg.id
    left join security_users su on s.author_id = su.id
    where s.node=N and s.visible=N order by pp.featured desc, global_rate desc limit N[/sql]

    кол-во записей в таблица

    portal_pictures 9295 записей
    comments 270
    portal_rates 1078
    struct_views 16556
    struct 23684
    security_users 6120

    я понимаю что это далеко не полная инфа, но всё же. Заранее спасибо =)
     
  2. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Мне кажется, надо подзапросы "select count(*)" убрать и сделать их отдельным запросом с union, а потом в PHP результату array_sum().
     
  3. Anonymous

    Anonymous Guest

    +1. теоретически - не надо, практически - муся не оптимизирует подзапросы.
     
  4. neverlose

    neverlose Активный пользователь

    С нами с:
    27 авг 2008
    Сообщения:
    1.112
    Симпатии:
    20
    [sql]
    SELECT
    pp.*, s.*, sg.name AS genre_name, sg.alias AS genre_alias, su.login as author_login,
    (COUNT(comments.datetime) + COUNT(portal_rates.datetime) + COUNT(struct_views.datetime)) AS global_rate
    FROM portal_pictures AS pp
    INNER JOIN struct AS s ON (pp.struct_id = s.id AND
    s.node=N AND
    s.visible=N)
    LEFT JOIN struct sg ON pp.genre_id = sg.id
    LEFT JOIN security_users su on s.author_id = su.id
    LEFT JOIN comments ON (s.id = comments.primary_id AND
    comments.table_id = N AND
    comments.datetime > NOW() - INTERVAL N DAY)
    LEFT JOIN portal_rates ON (s.id = portal_rates.struct_id AND
    portal_rates.datetime > NOW() - INTERVAL N DAY)
    LEFT JOIN struct_views ON (s.id = struct_views.struct_id AND
    struct_views.datetime > NOW() - INTERVAL N DAY)
    ORDER BY pp.featured DESC, global_rate DESC
    LIMIT N
    [/sql]

    P.S. Поставь индексы на поля, по которым идёт JOIN.
     
  5. Denis

    Denis Активный пользователь

    С нами с:
    5 фев 2006
    Сообщения:
    92
    Симпатии:
    0
    Адрес:
    Украина, Одесса
    О спасибо вот как сам как-то подумал, пока только начинаю осваивать MySQL
     
  6. Denis

    Denis Активный пользователь

    С нами с:
    5 фев 2006
    Сообщения:
    92
    Симпатии:
    0
    Адрес:
    Украина, Одесса
    Вот сразу вопрос в догонку, есть таблица в ней уже есть индексы и например записей всего 270 и параметр Cardinality тоже 270, я так понял от него толку мало в таком случае да?. Вот и сам вопрос: можно ли посносить все индексы и понасоздавать свои, без ущерба таблице и потере каких=то данных
     
  7. neverlose

    neverlose Активный пользователь

    С нами с:
    27 авг 2008
    Сообщения:
    1.112
    Симпатии:
    20
    Без проблем.
     
  8. decoder

    decoder Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    469
    Симпатии:
    0