Delgus
@Delgus

Как оптимизировать sql запрос?

Есть 2 таблицы -
statement(заявки)
id email snils inn date_create

cert_data(данные сертификатов)

id number prop value


В таблице cert_data данные расположены вертикально,тоесть, например
id number prop value
1 lalalala email mail@work.com
2 lalalala snils 123123123123
3 lalala inn 321321321321


Мне необходимо получить список id заявок(statement.id) и номеров сертификатов (cert_data.number), у которых
  1. совпадают email
  2. совпадают snils
  3. совпадают inn
  4. От времени заявки до создания сертификата прошло не более 60 дней


Важно! Одной заявке могут соответствовать несколько сертификатов. Мне нужны все. Поэтому LEFT JOIN не могу использовать.

Ну и я собственно говоря вписал все в один запрос:
SELECT `statement`.`id`,`cd1`.`number` FROM `statement`
            JOIN cert_data as cd1
            ON(cd1.value = `statement`.`email` AND cd1.prop = 'email')
            JOIN cert_data as cd2
            ON(cd2.value = `statement`.`organisation_inn` AND cd2.prop = 'inn')
            JOIN cert_data as cd3
            ON(cd3.value = `statement`.`snils` AND cd3.prop = 'snils')
            JOIN cert_data as cd4
            ON(cd4.prop = 'valid_from_time' AND cd4.value < (`statement`.`date_create` + 60*24*3600))
            WHERE `cd1`.`number` = `cd2`.`number` 
                  AND `cd2`.`number`=`cd3`.`number`
            AND statement.status='payment' AND (statement.number='0' OR statement.number='' OR statement.number IS NULL)


В таблице statement - 12000 записей, в таблице cert_data - 220000.

Работает этот запрос очень-очень долго.
Сначала памяти не хватило PHP PDO - отвалился с Fatal error...
Потом ждал минут 30, apache умер в openserver...Так и не дождался...
Если поставить LIMIT 50, то запрос выполняется 10 секунд.

Разбиваю все на 4 запроса(приведу 2 для примера)
SELECT `statement`.`id`,`cert_data`.`number` FROM `statement` 
             JOIN cert_data ON(cert_data.prop = 'snils'
               AND statement.status='payment' 
                  AND (statement.number='0' 
                  OR statement.number='' 
                  OR statement.number IS NULL) 
               AND cert_data.value = `statement`.`snils`;

            SELECT `statement`.`id`,`cert_data`.`number` FROM `statement` 
             JOIN cert_data 
             ON(
              cert_data.prop = 'inn' 
              AND statement.status='payment' 
              AND (statement.number='0' 
                  OR statement.number='' 
                  OR statement.number IS NULL)
              AND cert_data.value = `statement`.`organisation_inn`)"
        );


И оказывается, если разбить на 4 запроса и потом соединить результаты на серверном языке (а это php 5.6) то это будет быстрее. Но как так? Ведь все говорят что один запрос быстрее чем 4? Так ведь это всего то join 200000 записей, не миллионы же?
Подскажите возможно ли ускорить работу этого запроса, может неправильно составил?
  • Вопрос задан
  • 105 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы