Оптимизация запросов Mysql для union all query

#mysql

#mysql

Вопрос:

Я новичок в mysql и хочу знать, какая конфигурация мне нужна для поддержки 50 миллионов считываемых данных из mysql 5.7 Конфигурация сервера Mysql составляет 125 ГБ памяти и 100 ГБ дискового пространства.

Я хочу знать, какую глобальную конфигурацию и потоки мне нужно установить, например, размер innodb_buffer и т.д., Чтобы эффективно обрабатывать большие объемы данных.

Я загружаю данные в таблицы данных, используя php / mysql 5.7, и это действительно беспокойно и занимает около 5 минут.

Ниже приведен запрос,

 SELECT
`u`.`user_id`,
IF(
    MAX(ac.account_type) = 'ADVERTISER',
    MAX(a.clientname),
    MAX(p.name)
) AS contact_name,
`ac`.`account_type`,
MAX(c.campaignid) AS campaignid,
MAX(c.campaignname) AS campaignname,
MAX(z.zoneid) AS zoneid,
MAX(z.zonename) AS zonename,
MAX(c.clientid) AS clientid,
MAX(s.date_time) AS date_time,
SUM(s.requests) AS total_requests,
SUM(s.impressions) AS total_views,
SUM(s.clicks) AS total_clicks,
SUM(s.conversions) AS total_conversions,
SUM(s.total_revenue) AS total_revenue,
SUM(s.total_basket_value) AS total_basket_value,
SUM(s.total_num_items) AS total_num_items,
MAX(z.delivery) AS delivery
FROM
    (
    SELECT
        interval_start AS date_time,
        creative_id AS ad_id,
        zone_id,
        0 AS impressions,
        0 AS clicks,
        0 AS conversions,
        0 AS requests,
        total_cost * COUNT AS total_revenue,
        0 AS total_basket_value,
        0 AS total_num_items
    FROM
        rv_data_bkt_revenue
    WHERE
        creative_id > 0
    UNION ALL
SELECT
    interval_start AS date_time,
    creative_id AS ad_id,
    zone_id,
    0 AS impressions,
    COUNT AS clicks,
    0 AS conversions,
    0 AS requests,
    0 AS total_revenue,
    0 AS total_basket_value,
    0 AS total_num_items
FROM
    rv_data_bkt_c
WHERE
    creative_id > 0
UNION ALL
SELECT
    interval_start AS date_time,
    creative_id AS ad_id,
    zone_id,
    COUNT AS impressions,
    0 AS clicks,
    0 AS conversions,
    0 AS requests,
    0 AS total_revenue,
    0 AS total_basket_value,
    0 AS total_num_items
FROM
    rv_data_bkt_m
WHERE
    creative_id > 0
UNION ALL
SELECT
    MAX(date_time) AS date_time,
    creative_id AS ad_id,
    MAX(zone_id) AS zone_id,
    0 AS impressions,
    0 AS clicks,
    COUNT(creative_id) AS conversions,
    0 AS requests,
    0 AS total_revenue,
    0 AS total_basket_value,
    0 AS total_num_items
FROM
    rv_data_bkt_a
WHERE
    creative_id > 0
GROUP BY
    creative_id
UNION ALL
SELECT
    *
FROM
    (
    SELECT
        interval_start AS date_time,
        ad_id,
        zone_id,
        impressions,
        clicks,
        conversions,
        requests,
        0 AS total_revenue,
        total_basket_value,
        total_num_items
    FROM
        rv_data_intermediate_ad
    WHERE
        ad_id > 0
) e
) AS s
INNER JOIN rv_zones AS z
ON
    `z`.`zoneid` = `s`.`zone_id`
INNER JOIN rv_banners AS b
ON
    `s`.`ad_id` = `b`.`bannerid`
INNER JOIN rv_campaigns AS c
ON
    `b`.`campaignid` = `c`.`campaignid`
LEFT JOIN rv_affiliates AS p
ON
    `z`.`affiliateid` = `p`.`affiliateid`
LEFT JOIN rv_clients AS a
ON
    `a`.`clientid` = `c`.`clientid`
INNER JOIN rv_users AS u
ON
    `u`.`default_account_id` = `a`.`account_id` OR `u`.`default_account_id` = `p`.`account_id`
INNER JOIN rv_accounts AS ac
ON
    `u`.`default_account_id` = `ac`.`account_id` OR `u`.`default_account_id` = `ac`.`account_id` AND `u`.`default_account_id` IS NOT NULL
WHERE
    `ac`.`account_id` IN(
        '7',
        '9',
        '10'
    )
GROUP BY
    `u`.`user_id`,
    `ac`.`account_type`
  

Комментарии:

1. этот запрос занимает 5 минут? или загрузка данных занимает 5 минут?

2. покажите (текст!) вывод show create table yourtablename для всех таблиц, которые он использует, и вывод explain select... для этого запроса, пожалуйста

3. выполнение запроса занимает 5 минут.

Ответ №1:

хорошая идея — создать «Временные таблицы» вместо использования ОБЪЕДИНЕНИЯ, которое вы просто ВСТАВЛЯЕТЕ во временную таблицу, чтобы вы могли использовать эту таблицу позже в подзапросе, надеюсь, это поможет..

 CREATE TEMPORARY TABLE temp_table_name
SELECT Field1, Field2, FieldN  FROM original_tableA
LIMIT 0;
INSERT INTO temp_table_name
SELECT Field1, Field2, FieldN
FROM TABLE_B;
INSERT INTO temp_table_name
SELECT Field1, Field2, FieldN
FROM TABLE_B;
  

/ Здесь вы можете запросить ваше имя_таблицы наконец, вы можете отказаться от этого/

Комментарии:

1. Не могли бы вы преобразовать приведенный выше запрос в то, что вы предлагаете, все имена полей упомянуты, с уважением 🙂