Pergunta

A query for reading orders is very slow. I've tried a lot of things, but couldn't get a faster query. Below the query and the database tables. Of course, all the important fields have an index. I noticed that removing the group by function will speed it up, but grouping the query is important.

is there a better way for getting the orders? Thanks in advance.

SELECT
orders.id AS orderId, orders.delivery_from, orders.delivery_to,
orders_products.product_id, orders_products.color_id, ,orders_products.size_id,
sum(orders_products.quantity) as quantity,
customers.id AS customerId, customers.name AS customerName,
products.name
FROM orders
    INNER JOIN orders_products ON orders_products.order_id=orders.id
    INNER JOIN customers ON customers.id=orders.customer_id
    INNER JOIN products ON orders_products.product_id=products.id
    LEFT JOIN orders_product_data ON orders_product_data.order_id=orders.id AND orders_product_data.product_id=orders_product.product_id AND orders_product_data.color_id=orders_product.color_id
WHERE orders.status='0' AND
(orders.delivery_from<='2014-05-05' AND orders.delivery_to>='2014-05-05') AND
((orders_products_data.delivery_from<='2014-05-05' || orders_products_data.delivery_to=0) AND (orders_products_data.delivery_from>='2014-05-05' || orders_products_data.delivery_to=0))
GROUP BY customer_id, product_id, color_id, size_id

Customers

CREATE TABLE IF NOT EXISTS `customers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(90) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);

Products

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);

Orders

CREATE TABLE IF NOT EXISTS `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customer_id` int(11) NOT NULL,
  `delivery_from` date NOT NULL,
  `delivery_to` date NOT NULL,
  `status` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

Products of the order

CREATE TABLE IF NOT EXISTS `orders_products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL DEFAULT '0',
  `product_id` int(11) NOT NULL DEFAULT '0',
  `color_id` int(11) NOT NULL DEFAULT '0',
  `size_id` int(11) NOT NULL DEFAULT '0',
  `quantity` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

Color data. The tabel below stores for the combination order_id, product_id and color_id the delivery information since the delivery of products in different colors could change.

CREATE TABLE IF NOT EXISTS `orders_products_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL DEFAULT '0',
  `product_id` int(11) NOT NULL DEFAULT '0',
  `color_id` int(11) NOT NULL DEFAULT '0',
  `delivery_from` date NOT NULL,
  `delivery_to` date NOT NULL,
  PRIMARY KEY (`id`)
);

The explain query enter image description here

Foi útil?

Solução

You have mentioned that you have indexes for all the important fields.

Just for your Info - Index should be prepared based on the access path rather than for important fields.

Check after replacing delivery_from between '...' and '...' for orders, orders_product_data and adding following index: create index idx_orders_status_delivery_from_to on orders(status,delivery_from,delivery_to);

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top