Ускорение MySQL запроса - PullRequest
0 голосов
/ 23 октября 2018

У меня есть запрос mysql для объединения четырех таблиц, и я подумал, что лучше всего объединять таблицы, но теперь, когда данные mysql становятся больше, запрос, кажется, заставляет приложение останавливать выполнение.

 SELECT 
                        `purchase_order`.`id`, 
                        `purchase_order`.`po_date` AS po_date, 
                        `purchase_order`.`po_number`, 
                        `purchase_order`.`customer_id` AS customer_id , 
                        `customer`.`name` AS customer_name, 
                        `purchase_order`.`status` AS po_status, 
                        `purchase_order_items`.`product_id`, 
                        `purchase_order_items`.`po_item_name`, 
                        `product`.`weight` as product_weight,
                        `product`.`pending` as product_pending,
                        `product`.`company_owner` as company_owner,
                        `purchase_order_items`.`uom`, 
                        `purchase_order_items`.`po_item_type`, 
                        `purchase_order_items`.`order_sequence`, 
                        `purchase_order_items`.`pending_balance`, 
                        `purchase_order_items`.`quantity`, 
                        `purchase_order_items`.`notes`, 
                        `purchase_order_items`.`status` AS po_item_status,
                        `purchase_order_items`.`id` AS po_item_id
                      FROM `purchase_order` 
                      INNER JOIN customer ON `customer`.`id` = `purchase_order`.`customer_id`  
                      INNER JOIN purchase_order_items ON `purchase_order_items`.`po_id` = `purchase_order`.`id` 
                      INNER JOIN product ON `purchase_order_items`.`product_id` = `product`.`id`
GROUP BY id ORDER BY `purchase_order`.`po_date` DESC LIMIT 0, 20

enter image description here

Моя проблема на самом деле - это запрос, выполнение которого занимает много времени.Есть ли способ ускорить этот запрос или изменить этот запрос для более быстрого поиска данных?

вот EXPLAIN EXTENED, как было запрошено в комментариях.enter image description here Заранее спасибо, я действительно надеюсь, что это правильный канал для меня, чтобы спросить.Если нет, пожалуйста, дайте мне знать.

Ответы [ 4 ]

0 голосов
/ 25 октября 2018

Это даст вам правильный список идентификаторов?

SELECT id
    FROM purchase_order
    ORDER BY`po_date` DESC
    LIMIT 0, 20

Если это так, то запустите с этим до запуска в JOIN.Вы также можете (я думаю) избавиться от GROUP BY, который вызывает «взрыв-взрыв» строк.

SELECT ...
    FROM ( SELECT id ... (as above) ...) AS ids
    JOIN purchase_order po  ON po.id = ids.id
    JOIN ... (the other tables)
    GROUP BY ...   -- (this may be problematic, especially with the LIMIT)
    ORDER BY po.po_date DESC   -- yes, this needs repeating
    -- no LIMIT

Что-то вроде этого

SELECT 
                        `purchase_order`.`id`, 
                        `purchase_order`.`po_date` AS po_date, 
                        `purchase_order`.`po_number`, 
                        `purchase_order`.`customer_id` AS customer_id , 
                        `customer`.`name` AS customer_name, 
                        `purchase_order`.`status` AS po_status, 
                        `purchase_order_items`.`product_id`, 
                        `purchase_order_items`.`po_item_name`, 
                        `product`.`weight` as product_weight,
                        `product`.`pending` as product_pending,
                        `product`.`company_owner` as company_owner,
                        `purchase_order_items`.`uom`, 
                        `purchase_order_items`.`po_item_type`, 
                        `purchase_order_items`.`order_sequence`, 
                        `purchase_order_items`.`pending_balance`, 
                        `purchase_order_items`.`quantity`, 
                        `purchase_order_items`.`notes`, 
                        `purchase_order_items`.`status` AS po_item_status,
                        `purchase_order_items`.`id` AS po_item_id
    FROM (SELECT id, po_date, po_number, customer_id, status
            FROM purchase_order
            ORDER BY `po_date` DESC
            LIMIT 0, 5) as purchase_order 
    INNER JOIN customer ON `customer`.`id` = `purchase_order`.`customer_id`  
    INNER JOIN purchase_order_items
         ON `purchase_order_items`.`po_id` = `purchase_order`.`id` 
    INNER JOIN product ON `purchase_order_items`.`product_id` = `product`.`id`
    GROUP BY purchase_order.id DESC
    LIMIT 0, 5
0 голосов
/ 23 октября 2018

Так как вы упомянули, что данные становятся больше.Я бы предложил сделать шардинг, и тогда вы можете распараллелить несколько запросов.Пожалуйста, обратитесь к следующей статье

Параллельный запрос для MySQL с Shard-Query

0 голосов
/ 23 октября 2018

Во-первых, я немного почистил читабельность.Вам не нужно отмечать tick вокруг каждой ссылки на table.column.Также, для краткости, использование псевдонимов работает хорошо.Например: «po» вместо «purchase_order», «poi» вместо «purchase_order_items».Единственный раз, когда я бы использовал тиковые метки, это зарезервированные слова, которые могут вызвать проблему.

Во-вторых, у вас нет никаких агрегаций (сумма, мин, максимум, количество, среднее и т. Д.) В вашем запросе.так что вы должны иметь возможность удалить предложение GROUP BY.

Что касается индексов, я должен предположить, что у вас есть индекс в ваших ссылочных таблицах для соответствующих им столбцов ключа "id".

Для вашей таблицы заказов на покупку у меня будет индекс на основе «po_date» в первой позиции поля индекса, если у вас уже есть индекс, использующий его.Так как ваш Order by находится на этом, позвольте движку сначала перейти к этим датированным записям, и ваш порядок убывания будет решен.

SELECT 
      po.id, 
      po.po_date, 
      po.po_number, 
      po.customer_id, 
      c.`name` AS customer_name, 
      po.`status` AS po_status, 
      poi.product_id, 
      poi.po_item_name, 
      p.weight as product_weight,
      p.pending as product_pending,
      p.company_owner,
      poi.uom, 
      poi.po_item_type, 
      poi.order_sequence, 
      poi.pending_balance, 
      poi.quantity, 
      poi.notes, 
      poi.`status` AS po_item_status,
      poi.id AS po_item_id
   FROM 
      purchase_order po
         INNER JOIN customer c
            ON po.customer_id = c.id
         INNER JOIN purchase_order_items poi 
            ON po.id = poi.po_id
            INNER JOIN product p 
               ON poi.product_id = p.id
   ORDER BY 
      po.po_date DESC 
   LIMIT 
      0, 20
0 голосов
/ 23 октября 2018

Вы должны быть уверены, что purchase_order.po_date и все столбцы id проиндексированы.Вы можете проверить это с помощью запроса ниже.

SHOW INDEX FROM yourtable;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...