За последние 24 часа нас посетили 20045 программистов и 1695 роботов. Сейчас ищет 1831 программист ...

Грамотный запрос в несколько таблиц

Тема в разделе "MySQL", создана пользователем Intrerio, 5 окт 2017.

  1. Intrerio

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

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    Здравствуйте друзья. Для начала представлю Вам свой запрос:
    PHP:
    1. $sql = 'SELECT DISTINCT blanks.id,blanks.nomer,blanks.date_start,blanks.date_end,blanks.bank_kv,'
    2.                         . 'blanks.date_insert,blanks.price_manual,blanks.price_correct,blanks.comment_remark,blanks.suma_payment,blanks.date_payment,'
    3.                         . 'blanks.polis_dublikat,blanks.date_dublikat,blanks.status AS status_id,'
    4.                         . 'status.nazva AS status,'
    5.                         . 'pidrozdil.nazva AS pidrozdil_nazva,'
    6.                         . 'viddilennia.nazva AS viddilennia_nazva,'
    7.                         . 'a.pip AS agent_pip, '
    8.                         . 'c.pip AS client_pip,c.inp,c.adress,c.birthday,c.phone, '
    9.                         . 'oscpv_blank.bonus, oscpv_blank.franshyza,'
    10.                         . 'oscpv_avto.type_tz,oscpv_avto.nomer AS nomer_tz,oscpv_avto.marka,oscpv_avto.model,oscpv_avto.misto,oscpv_avto.zona,'
    11.                         . 'oscpv_avto.vin,oscpv_avto.rik '                      
    12.                         . 'FROM blanks '
    13.                         . 'LEFT JOIN pidrozdil ON blanks.pidrozdil=pidrozdil.id '
    14.                         . 'LEFT JOIN viddilennia ON blanks.viddilennia=viddilennia.id '
    15.                         . 'LEFT JOIN users a ON blanks.komu_peredacha=a.id '
    16.                         . 'LEFT JOIN oscpv_blank ON blanks.id=oscpv_blank.blank_id '
    17.                         . 'LEFT JOIN users c ON oscpv_blank.client_id=c.id '
    18.                         . 'LEFT JOIN oscpv_avto ON oscpv_blank.avto_id=oscpv_avto.id '
    19.                         . 'LEFT JOIN status ON status.id = blanks.status '                      
    20.                         . 'WHERE reestr_rd = :id ORDER BY nomer ASC';
    Теперь несколько слов о важных местах. Таблица blanks - 300000 записей, таблица oscpv_blank - 240 000 записей, таблица status - названия статусов договоров(около 5 записей).
    Запускаем запрос и получаме запись в slow.log (около 6 секунд). Меняем LEFT JOIN oscpv_blank на INNER JOIN oscpv_blank запрос прям летит но!!! не выводяться некоторые договора. Теперь более детально. В таблице blanks все договора компании (заключенные, чистые, испорчены и так далее). В таблице oscpv_blank ифонрмация по самому договору если он заключен. Тоесть, в таблицу oscpv_blank попадают не все договора с первой таблици. Значит когда мы делаем внутренний JOIN то получаме лишь то что однозначно есть в oscpv_blank, а нам то нужно не только те что есть там. А если делаем LEFT JOIN то запрос нагружает машину. Как посоветуете переделать запрос?
     
  2. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    explain? индексы?
     
  3. Intrerio

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

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    Оказалось все на много проще. В таблице blanks поле id имеет тип INT а в oscpv_blank поле blank_id имеет тип VARCHAR, а как известно индексы должны иметь одинаковый тип. Поменял blank_id на INT и запрос полетел а с ним и slow.log опустел.Проблема решена
     
  4. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Такое бывает, когда вместо использования внешних ключей архитектор БД полагается на человеческий фактор.