我有这样的模型:
Customer (1) .... (n) Orders
我可以通过如下简单查询找到一位客户的所有订单:
select * from Orders o join Customer c on o.customer_id = c.id;
我需要找到所有客户的所有当前(今天)订单(如果有),并呈现所有客户。
例如。我期待的结果是这样的:
Customer OrderDate OrderStatus
Customer 1 2/1/2015 12:00:00 active
Customer 2 2/1/2015 13:00:00 closed
Customer 3 null null
Customer 4 null null
表格应该如下所示:
Customers
Customer 1
Customer 2
Customer 3
Customer 4
Orders timestamp CustomerID
Active 1/1/2015 15:00:00 1
Closed 1/1/2015 08:00:00 1
Canceled 1/1/2015 09:00:00 1
Closed 2/1/2015 11:00:00 1
Active 2/1/2015 12:00:00 1 //This is the last one of "TODAY" C1
Active 3/1/2015 18:00:00 1
Closed 2/1/2015 13:00:00 2 //This is the last one of "TODAY" C2
正在运行的查询是:
select o.status, o.date, c.name from (
select c.*, (
select o1.id from orders o1
where o1.id_customer = c.id and o1.date between '2/1/2015 00:00:00' and "2/1/2015 23:59:59"
order by o1.date desc limit 1) as o
from cliente c
) c left join orders o on o.id = c.o;
问题在于,对于少量订单和客户,查询需要几秒钟的时间才能执行。我预计短期内订单数量将会增加,客户数量也会增加。
有没有办法提高这个查询的效率?我觉得我解决问题的方式是错误的。
旁注:我无法修改模型,也无法包含新列。我的第一个解决方案是包含给客户的最后一个订单,并在每次创建订单时进行设置,但遗憾的是我无法更改数据库。
提前致以问候和感谢!
[编辑]
表定义
CREATE TABLE `customer` (
`id` char(36) NOT NULL,
`name` varchar(120) NOT NULL,
`cabin` enum('CABIN_A','CABIN_B','CABIN_C','CABIN_D','CABIN_E') DEFAULT NULL,
`addressId` char(36) NOT NULL,
`phone` varchar(45) DEFAULT NULL,
`datetime` timestamp NULL DEFAULT NULL,
`number` bigint(20) unsigned NOT NULL,
`unitId` char(36) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `number_UNIQUE` (`number`),
KEY `addressId_idx` (`addressId`),
KEY `fk_customer_unit_idx` (`unitId`),
CONSTRAINT `fk_customer_unit` FOREIGN KEY (`unitId`) REFERENCES `unidad` (`unitId`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_address_customer` FOREIGN KEY (`addressId`) REFERENCES `address` (`addressId`) ON DELETE CASCADE ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `orders` (
`id` char(36) NOT NULL,
`customerId` char(36) NOT NULL,
`status` enum('ACTIVE','CLOSED','CANCELED') NOT NULL,
`datetime` timestamp NULL DEFAULT NULL,
`comment` varchar(700) DEFAULT NULL,
`programDate` timestamp NULL DEFAULT NULL,
`cabin` varchar(10) DEFAULT NULL,
`unitId` char(36) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `fk_orders_unit_idx` (`unitId`),
CONSTRAINT `fk_customer_orders` FOREIGN KEY (`customerId`) REFERENCES `customer` (`customerId`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_unit` FOREIGN KEY (`unitId`) REFERENCES `unit` (`unitId`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
最佳答案
一个没有子查询的简单LEFT JOIN
应该可以加快速度:
select o.status, o.date, c.name
from Orders o
join Customer c
on o.customer_id = c.id
AND o.orderDate = '2/1/2015'
我假设,根据最初的问题(来自“我期待的结果...”),您希望为今天没有订单的任何客户返回 NULL。
我有点困惑为什么客户 #1 的 2 个“已关闭”订单和 1 个“已取消”订单不属于“我期望的结果”的一部分,因为您不需要 orderStats = 'Active'
在您的“正在运行的查询”中...显然,由于您列出了客户 #2 的已关闭订单,因此实际上并不要求订单处于打开状态 - 也许您想详细说明这一点。
关于mysql - 有没有办法提高这个查询的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29250125/