[英]Why using inner join itself is more faster than where
这是我的桌子:
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);
ID | 选择类型 | 桌子 | 分区 | 类型 | 可能的键 | 钥匙 | 密钥长度 | 参考 | 行 | 过滤 | 额外的 |
---|---|---|---|---|---|---|---|---|---|---|---|
1个 | 简单的 | cerp_oms_order | null | 全部 | 基本的 | null | null | null | 60787 | 10 | 在哪里使用 |
1个 | 简单的 | cerp_oms_order | null | eq_ref | 基本的 | 基本的 | 8个 | cerp_oms_1.cerp_oms_order.id | 1个 | 100 | null |
使用内部连接execution: 7 ms, fetching: 109 ms
VS
explain
select *
from cerp_oms_order
where source_type = 43
order by created_time;
ID | 选择类型 | 桌子 | 分区 | 类型 | 可能的键 | 钥匙 | 密钥长度 | 参考 | 行 | 过滤 | 额外的 |
---|---|---|---|---|---|---|---|---|---|---|---|
1个 | 简单的 | cerp_oms_order | null | 全部 | null | null | null | null | 60787 | 10 | 在哪里使用; 使用文件排序 |
使用简单的 where 子句execution: 80 ms, fetching: 138 ms
我不明白为什么使用inner join
可以加速我的 sql?
如果你有
INDEX(source_type, created_time)
两种配方都会运行得更快。 而且,我认为,第二个会更快。
至于“为什么”。 看看第二个做了什么:
source_type = 43
的行。*
) 收集到一个临时表中。id
的子查询要庞大。 使用INDEX
我建议:
source_type = 43
的所有“行”。created_time
排序,现在或以后都不需要“排序”传递。id
。 (这就是 InnoDB 到达列的 rest 的方式),所以*
) 列。 请注意, JOIN
版本的工作原理基本相同,但从技术上讲, ORDER BY
可能会丢失。 如果它确实丢失了,您将需要添加第二个ORDER BY
,从而强制进行排序。
(不相关)您的“KEY cerp_oms_order_company_id_index
( company_id
)”可以删除,因为还有另外两个以company_id
开头的索引。
有关优化索引的更多信息: Index Cookbook
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.