你好,
我有以下 SQL 查询,运行大约需要 4 秒:
select
o.id, tu.status_type, m.upload_date
from
(select order_id, max(last_updated) as maxudate from tracking_update group by order_id) t
inner join
tracking_update tu on t.order_id=tu.order_id and t.maxudate=tu.last_updated
right join
fgw247.order o on t.order_id=o.id
left join
manifest m on o.manifest_id=m.id
where
(m.upload_date >= '2015-12-12 00:00:00') or (m.upload_date <='2015-12-12 00:00:00' and tu.status_type != 'D' and tu.status_type != 'XD')
该查询连接以下 3 个表:
订单、清单和 Tracking_Update。
该查询将返回满足以下条件的订单:
- 任何交货状态的订单 < 30 天
- 订单 > 30 天,而不是交货状态
如果该订单的最新 tracking_update 的 status_type 为“D”或“XD”,则该订单被视为已送达
现在,订单列在订单表中。Order 表有一个名为 manifest_id 的列,它引用了在上传订单时创建的 Manifest。
一个清单可以有多个订单。这用于确定过去 30 天内是否已上传订单。
最后, tracking_update 表包含每个订单的 tracking_updates。一个订单可以有多个 tracking_updates。
目前,tracking_update 表的记录长度超过 1M。
下面列出了每个表的创建语句:
CREATE TABLE "order" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"ShipmentId" varchar(50) DEFAULT NULL,
"RecipientName" varchar(160) DEFAULT NULL,
"CompanyName" varchar(160) DEFAULT NULL,
"Address1" varchar(160) DEFAULT NULL,
"Address2" varchar(160) DEFAULT NULL,
"City" varchar(50) DEFAULT NULL,
"State" varchar(3) DEFAULT NULL,
"ZIP" int(11) DEFAULT NULL,
"TEL" int(11) DEFAULT NULL,
"Email" varchar(255) DEFAULT NULL,
"Bottles" int(11) DEFAULT NULL,
"Weight" float DEFAULT NULL,
"Resi" tinyint(1) DEFAULT NULL,
"Wave" int(11) DEFAULT NULL,
"url_slug" varchar(50) DEFAULT NULL,
"manifest_id" int(11) DEFAULT NULL,
"shipment_date" datetime DEFAULT NULL,
"tracking_number" varchar(30) DEFAULT NULL,
"shipping_carrier" varchar(10) DEFAULT NULL,
"last_tracking_update" datetime DEFAULT NULL,
"delivery_date" datetime DEFAULT NULL,
"customer_code" varchar(50) DEFAULT NULL,
"sub_cust_code" int(11) DEFAULT NULL,
PRIMARY KEY ("id"),
UNIQUE KEY "ShipmentID" ("ShipmentId"),
KEY "manifest_id" ("manifest_id"),
KEY "order_idx3" ("tracking_number"),
KEY "order_idx4" ("customer_code"),
CONSTRAINT "order_ibfk_1" FOREIGN KEY ("manifest_id") REFERENCES "manifest" ("id")
);
Tracking_Update 表:
CREATE TABLE "tracking_update" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"order_id" int(11) DEFAULT NULL,
"ship_update_date" datetime DEFAULT NULL,
"message" varchar(400) DEFAULT NULL,
"location" varchar(100) DEFAULT NULL,
"status_type" varchar(2) DEFAULT NULL,
"last_updated" datetime DEFAULT NULL,
"hash" varchar(32) DEFAULT NULL,
PRIMARY KEY ("id"),
KEY "order_id" ("order_id"),
KEY "tracking_update_idx2" ("status_type"),
KEY "tracking_update_idx3" ("ship_update_date"),
CONSTRAINT "tracking_update_ibfk_1" FOREIGN KEY ("order_id") REFERENCES "order" ("id")
);
清单表:
CREATE TABLE "manifest" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"upload_date" datetime DEFAULT NULL,
"name" varchar(100) DEFAULT NULL,
"destination_gateway" varchar(40) DEFAULT NULL,
"arrived" tinyint(1) DEFAULT NULL,
"customer_code" varchar(50) DEFAULT NULL,
"upload_user" varchar(50) DEFAULT NULL,
"trip_id" int(11) DEFAULT NULL,
PRIMARY KEY ("id")
);
这里也是用 JSON 导出的 select 语句的解释:
{
"data":
[
{
"id": 1,
"select_type": "PRIMARY",
"table": "m",
"type": "ALL",
"possible_keys": "PRIMARY",
"key": null,
"key_len": null,
"ref": null,
"rows": 220,
"Extra": "Using where"
},
{
"id": 1,
"select_type": "PRIMARY",
"table": "o",
"type": "ref",
"possible_keys": "manifest_id",
"key": "manifest_id",
"key_len": "5",
"ref": "fgw247.m.id",
"rows": 246,
"Extra": "Using index"
},
{
"id": 1,
"select_type": "PRIMARY",
"table": "tu",
"type": "ref",
"possible_keys": "order_id",
"key": "order_id",
"key_len": "5",
"ref": "fgw247.o.id",
"rows": 7,
"Extra": "Using where"
},
{
"id": 1,
"select_type": "PRIMARY",
"table": "<derived2>",
"type": "ref",
"possible_keys": "<auto_key0>",
"key": "<auto_key0>",
"key_len": "11",
"ref": "fgw247.o.id,fgw247.tu.last_updated",
"rows": 13,
"Extra": "Using index"
},
{
"id": 2,
"select_type": "DERIVED",
"table": "tracking_update",
"type": "index",
"possible_keys": "order_id",
"key": "order_id",
"key_len": "5",
"ref": null,
"rows": 1388275,
"Extra": null
}
]
}
任何帮助表示赞赏
更新
这是我正在使用的当前查询,它更快:
SELECT
o.*, tu.*
FROM
fgw247.`order` o
JOIN
manifest m
ON
o.`manifest_id` = m.`id`
JOIN
`tracking_update` tu
ON
tu.`order_id` = o.`id` and tu.`ship_update_date` = (select max(last_updated) as last_updated from tracking_update where order_id = o.`id` group by order_id)
WHERE
m.`upload_date` >= '2015-12-14 11:50:12'
OR
(o.`delivery_date` IS NULL AND m.`upload_date` < '2015-12-14 11:50:12')
LIMIT 100