У меня есть две таблицы с огромным количеством данных в них (~ 1,8 мил в основной, ~ 1,2 мил во вторичной), а именно:
subscriber_table (id, name, email, country , account_status, ...) subscriber_payment_table (id, subscriber_id, payment_type, payment_credential)
Моя конечная цель - иметь таблицу, содержащую всех пользователей и их таблицы платежей (null, если не существует), до вчера , и с account_status = 1 (active)
Не у всех подписчиков есть соответствующий subscriber_payment, поэтому использование INNER JOIN не является жизнеспособным вариантом, а использование LEFT JOIN приводит к тому, что я получаю SQL тайм-аут моего запроса через 2 часа после больших усилий по обработке.
SELECT
`subscribers`.`id` AS `id`,
`subscribers`.`email` AS `email`,
`subscribers`.`name` AS `name`,
`subscribers`.`geoloc_country` AS `country`,
`subscribers_payment`.`payment_type` AS `paymentType`,
`subscribers_payment`.`payment_credential` AS `paymentCredential`
`subscribers`.`create_datetime` AS `createdAt`
FROM
`subscribers`
LEFT JOIN
`subscribers_payment` ON (`subscribers_payment`.`subscriberId` = `subscribers`.`id`)
WHERE
`subscribers`.`account_status` = 1
AND DATE_FORMAT(CAST(`subscribers`.`create_datetime` AS DATE), '%Y-%m-%d') < curdate())
Как уже упоминалось, этот запрос занимает слишком много времени и заканчивается тайм-аутом и не работает. Я также рассматривал возможность использования UNION между «Все подписчики» и «Подписчики с оплатой».
(
SELECT
`subscribers`.`id` AS `id`,
`subscribers`.`email` AS `email`,
`subscribers`.`name` AS `name`,
`subscribers`.`geoloc_country` AS `country`,
null AS `paymentType`,
null AS `paymentCredential`
`subscribers`.`create_datetime` AS `createdAt`
FROM
`subscribers`
WHERE
`subscribers`.`account_status` = 1
AND DATE_FORMAT(CAST(`subscribers`.`create_datetime` AS DATE), '%Y-%m-%d') < curdate()))
UNION
(
SELECT
`subscribers`.`id` AS `id`,
`subscribers`.`email` AS `email`,
`subscribers`.`name` AS `name`,
`subscribers`.`geoloc_country` AS `country`,
`subscribers_payment`.`payment_type` AS `paymentType`,
`subscribers_payment`.`payment_credential` AS `paymentCredential`
`subscribers`.`create_datetime` AS `createdAt`
FROM
`subscribers`
INNERJOIN
`subscribers_payment` ON (`subscribers_payment`.`subscriberId` = `subscribers`.`id`)
WHERE
`subscribers`.`account_status` = 1
AND DATE_FORMAT(CAST(`subscribers`.`create_datetime` AS DATE), '%Y-%m-%d') < curdate()))
Проблема с этой текущей реализацией заключается в том, что я получаю повторяющиеся запросы (я использую UNION, но он не группирует мои результаты вместе и не удаляет неотличимые значения, потому что у меня другое значение в столбцах paymentType
и paymentCredential
)
Этот запрос выполняется примерно за ~ 2 минуты, поэтому для меня посильнее. Мне просто нужно удалить повторяющиеся записи ... если здесь нет более разумного варианта
Отказ от ответственности: мы используем таблицы MyISAM, поэтому наличие внешних ключей для ускорения запросов - это не- go.