Есть 2 таблицы -
statement(заявки)
id | email | snils | inn | date_create |
---|
cert_data(данные сертификатов)
В таблице 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), у которых
- совпадают email
- совпадают snils
- совпадают inn
- От времени заявки до создания сертификата прошло не более 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 записей, не миллионы же?
Подскажите возможно ли ускорить работу этого запроса, может неправильно составил?