MySQL-запрос работает на одном сервере, но не на другом - PullRequest
0 голосов
/ 12 декабря 2018

Я перевожу наш MySQL Server (5.7.15) в более мощный выделенный блок (5.7.24, данные / схема, созданные mysqldump со старого сервера около двух недель назад), и мне приходится воссоздавать все настройки серверакоторые не сохраняются дампом MySQL.У меня есть этот запрос (не написано мной):

SELECT * 
FROM   (SELECT t1.job_status, 
               t1.customer_po, 
               t1.customer_name, 
               t1.order_value, 
               t1.code_division, 
               t1.assigned_sales_person, 
               t1.date_assigned, 
               t2.date_order, 
               IF(t1.job_status = 'PENDING', 
               Datediff(Curdate(), t1.date_assigned), 
               Datediff(t2.date_order, t1.date_assigned)) AS days, 
               force4.Code('DV', t1.code_division)        AS code_desc, 
               t2.order_id 
        FROM   customer_po_log AS t1 
               left join orders AS t2 
                      ON t2.po_id = t1.customer_po 
               left join order_item AS t3 
                      ON t3.order_id = t2.order_id 
                         AND t3.code_division = t1.code_division 
        GROUP  BY t1.customer_po) AS u1 
WHERE  u1.job_status = 'PENDING' 
       AND u1.code_division = 'L' 
ORDER  BY u1.days DESC 

На исходном сервере запрос завершается за 0,5 секунды.на новом сервере он превышает максимальное время запроса.Я почти уверен, что проблема связана с соединением t3, из-за чего инструмент «Объяснить текущее утверждение» говорит мне:

enter image description here enter image description here

Существует ли параметр, который блокирует выполнение этого запроса в новом окне?В чем причина разницы?

Рады предоставить любую дополнительную необходимую информацию.Спасибо!

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

(Было бы полезно иметь SHOW CREATE TABLE и EXPLAIN SELECT...)

Если у вас нет этих индексов, они могут помочь со скоростью (на обеих машинах):

t2:  (po_id, order_id, date_order)  -- with `po_id` first
t3:  (order_id, code_division)  -- in either order

Кроме того, соединение с t3 кажется совершенно бесполезным.Поскольку оптимизатор может быть недостаточно умен, чтобы удалить его для вас, вы должны сделать это.

И переместить WHERE внутрь

И избавиться от внешнего SELECT.

Ах, черт возьми, здесь:

SELECT  t1.job_status, t1.customer_po, t1.customer_name, t1.order_value,
        t1.code_division, t1.assigned_sales_person, t1.date_assigned,
        t2.date_order,
        Datediff(Curdate(), t1.date_assigned)) AS days,
        force4.Code('DV', t1.code_division) AS code_desc,
        t2.order_id
    FROM  customer_po_log AS t1
    LEFT JOIN  orders AS t2  ON t2.po_id = t1.customer_po
    WHERE  u1.job_status = 'PENDING'
      AND  u1.code_division = 'L'
    ORDER BY  u1.days DESC 

плюс

t1:  INDEX(job_status, code_division)  -- in either order
t2:  INDEX(po_id, order_id, date_order)  -- with `po_id` first

ОК, вы не написали код.Но теперь вы несете ответственность за его очистку.В противном случае следующий разработчик укажет пальцем на you .

0 голосов
/ 12 декабря 2018

При переносе таблиц с одного сервера на другой всегда проверяйте пару вещей:

  1. Вы уверены, что таблицы на новом сервере имеют те же индексы, что и на старом сервере??Сделайте SHOW CREATE TABLE tbl;, чтобы проверить.

  2. Вы сделали OPTIMIZE TABLE tbl; для каждой таблицы после их миграции?Вы также можете сделать это из командной строки с помощью mysqlcheck -o --all-databases

Оптимизация или анализ таблицы восстанавливает некоторую внутреннюю статистику.Эта статистика помогает планировщику запросов MySQL выбирать индексы, когда они помогают с запросом, поэтому иногда следует избегать полного сканирования таблицы или индекса.

...