这是我的桌子:
CREATE TABLE `cerp_oms_order` ( `id` bigint NOT NULL, `company_id` bigint NOT NULL, `order_no` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `source_type` int NOT NULL, `shop_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `outer_shop` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `origin_status` int NOT NULL, `system_status` int NOT NULL, `created_time` datetime DEFAULT NULL, `paid_time` datetime DEFAULT NULL, `sent_time` datetime DEFAULT NULL, `end_time` datetime DEFAULT NULL, `modify_time` datetime DEFAULT NULL, `delivery_deadline_time` datetime DEFAULT NULL, `amount` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `spu_kind` int NOT NULL, `sku_kind` int NOT NULL, `total_quantity` decimal(16,4) NOT NULL, `buyer_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `outer_buyer_identifier` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `tax_info` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `warehouse_owner` int DEFAULT NULL, `warehouse_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `logistics_type` int NOT NULL, `logistics_outer_info` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `delivery_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `delivery_no` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `wave_no` varchar(64) DEFAULT '', `is_deleted` tinyint NOT NULL DEFAULT '0', `backend_processing_type` tinyint NOT NULL, `create_type` tinyint NOT NULL, `is_hang_up` tinyint NOT NULL, `hang_up_case_type` smallint DEFAULT NULL, `hang_up_case_id` bigint DEFAULT NULL, `rc_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `rm_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `vat` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `weight` decimal(16,4) NOT NULL DEFAULT '0.0000', `volume` decimal(16,4) NOT NULL DEFAULT '0.0000', `is_abnormal` tinyint NOT NULL DEFAULT '0', `estimate_profit` decimal(16,4) NOT NULL DEFAULT '0.0000', `business_man_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `business_man` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `currency` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `net_amount_summary` decimal(19,4) NOT NULL, `domestic_amount` decimal(19,4) NOT NULL, `secret_key` varchar(64) DEFAULT '', `secretKey` varchar(255) DEFAULT NULL, `sale_id` bigint DEFAULT NULL, `total_refund_include_tax` decimal(16,4) NOT NULL DEFAULT '0.0000', `total_refund_money` decimal(16,4) NOT NULL DEFAULT '0.0000', `total_refund_tax` decimal(16,4) NOT NULL DEFAULT '0.0000', `total_return_goods` decimal(16,2) NOT NULL DEFAULT '0.00', PRIMARY KEY (`id`), UNIQUE KEY `key_order_no` (`order_no`), KEY `idx_order_company_id` (`company_id`,`created_time`), KEY `IDX_RM_TIME` (`rm_time`), KEY `IDX_IS_ABNORMAL` (`is_abnormal`), KEY `cerp_oms_order_company_id_index` (`company_id`), KEY `idx_order_company_status_deleted` (`company_id`,`is_deleted`,`system_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='system order table'
explain select *
from cerp_oms_order
inner join (select id
from cerp_oms_order
where source_type = 43
order by created_time) as tmp using (id);
使用内连接执行:7 ms,获取:109 ms
VS
explain
select *
from cerp_oms_order
where source_type = 43
order by created_time;
使用简单的where子句执行:80 ms,获取:138 ms
我不明白为什么使用内连接
可以加快我的sql?
如果你有
INDEX(source_type, created_time)
两种配方都会运行得更快。我认为,第二种会更快。
至于“为什么”。看看第二个做了什么:
source_type=43
的行。*
)收集到一个临时表中。id
的子查询要笨重。使用INDEX
我建议:
source_type=43
的行。created_time
排序的,所以现在或以后都不需要排序传递。id
。(这是InnoDB获取其余列的方式),所以*
)列。请注意,JOIN
版本的工作原理基本相同,但是从技术上讲,ORDER BY
可能会丢失。如果它确实丢失了,您需要添加第二个ORDER BY
,从而强制排序。
(无关)您的KEYcerp_oms_order_company_id_index
(company_id
)可以被删除,因为还有两个以company_id
开头的索引。
有关优化索引的更多信息:索引食谱