Ускорение MySQL-запроса / 2,9 млн строк / нескольких соединений - PullRequest
0 голосов
/ 20 января 2019

У меня есть запрос, который выполняется довольно медленно из-за таблицы, содержащей 2,9 млн строк и соединений с другими таблицами. Мне удалось наполовину сократить время выполнения, но оно все еще недостаточно быстро.

У кого-нибудь есть идеи о том, что еще я могу сделать? Все столбцы сумма, entityId, merchant.name, channel.uuid и channel.sender проиндексированы.

Это оригинальный запрос, который занимает 11 секунд ...

SELECT 
    SUM(t.amount) AS amount, 
    m.name 
FROM 
    transactionsV2 t
    JOIN channels c ON t.entityId = c.uuid
    JOIN merchants m ON c.sender = m.uuid
WHERE 
    t.paymentType = "DB"
    AND t.status = 1
    AND t.processing_time >= "2019-01-19 00:00:00"
    AND t.processing_time <= "2019-01-20 23:59:59"
GROUP BY m.uuid
ORDER BY m.name

Это переработанный запрос, который занимает 4,5 секунды ...

SELECT 
    SUM(t1.amount) AS amount, 
    m.name 
FROM
    (
        SELECT t.amount, t.entityId 
        FROM transactionsV2 t
        WHERE 
            t.paymentType = "DB"
            AND t.status = 1
            AND t.processing_time >= "2019-01-19 00:00:00"
            AND t.processing_time <= "2019-01-20 23:59:59"
    ) t1
    JOIN channels c ON t1.entityId = c.uuid
    JOIN merchants m ON c.sender = m.uuid
GROUP BY m.name

Ниже приведена структура таблицы для всех 3 таблиц.

enter image description here

enter image description here

enter image description here

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Я бы начал с переписывания запроса без производной таблицы:

SELECT SUM(t.amount) AS amount, 
       m.name 
FROM transactionsV2 t JOIN
     channels c
     ON t.entityId = c.uuid JOIN
     merchants m
     ON c.sender = m.uuid
WHERE t.paymentType = 'DB' AND
      t.status = 1 AND
      t.processing_time >= '2019-01-19' AND
      t.processing_time < '2019-01-21'
GROUP BY m.name;

Тогда вам нужны индексы, которые включают все столбцы для каждой таблицы. Если предположить, что transactionsV2 является таблицей, то:

  • transactionsV2(paymentType, status, processing_time, entityId, amount)
  • channels(uuid, sender)
  • merchants(uuid, name)

Идея состоит в том, чтобы сначала взять столбцы, начинающиеся с WHERE, с условиями равенства.

Если transactionsV2 является представлением, вам может не повезти, потому что MySQL затрудняет (невозможно?) Оптимизацию представлений.

0 голосов
/ 20 января 2019

просматривая ваш код, убедитесь, что у вас есть составной индекс на

transactionsV2 (paymentType, status, processing_time, entityId, amount)

channels (sender, uuid)

merchants ( uuid, name)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...