强制mysql查询优化器在JOIN之前使用WHERE条件

时间:2019-03-28 12:09:51

标签: mysql

我的查询联接两个表,并应用如下条件:

select b.address FROM  
address_partitions as c 
JOIN hop_addresses as b 
ON b.address=c.address 
AND c.npartition = 19;

+-----------------------------------+
| address                           |
+-----------------------------------+
| 111112UgMrsKETroaurM8YGf2R7SkN2wz |
+-----------------------------------+
1 row in set (10.08 sec)

mysql优化器总是先执行JOIN,然后执行条件:

| id   | select_type | table | type  | possible_keys      | key        | key_len | ref   | rows     | Extra                                                        |
|    1 | SIMPLE      | c     | ref   | PRIMARY,npartition | npartition | 4       | const |        1 | Using index                                                  |
|    1 | SIMPLE      | b     | index | NULL               | PRIMARY    | 38      | NULL  | 25249276 | Using where; Using index; Using join buffer (flat, BNL join) |

查询需要10秒

如果我分两个步骤手动执行查询,则条件为:

  1. 先条件

从address_partitions中选择地址,作为c WHERE c.npartition = 19;

+-----------------------------------+
| address                           |
+-----------------------------------+
| 111112UgMrsKETroaurM8YGf2R7SkN2wz |
+-----------------------------------+
1 row in set (0.00 sec)
  1. 然后加入

从hop_addresses中选择*,其中地址=“ 111112UgMrsKETroaurM8YGf2R7SkN2wz”;

+-----------------------------------+---------+-----------+--------------+
| address                           | no_hops | no_inputs | no_addresses |
+-----------------------------------+---------+-----------+--------------+
| 111112UgMrsKETroaurM8YGf2R7SkN2wz |       2 |        35 |            5 |
+-----------------------------------+---------+-----------+--------------+
1 row in set (0.00 sec)

查询需要0.00秒

如何在联接之前强制mysql查询优化器执行WHERE条件?

address_partitions | CREATE TABLE `address_partitions` (
  `address` varchar(36) NOT NULL,
  `npartition` int(10) unsigned NOT NULL,
  PRIMARY KEY (`address`),
  KEY `npartition` (`npartition`)
) ENGINE=InnoDB

hop_addresses | CREATE TABLE `hop_addresses` (
  `address` varchar(36) NOT NULL,
  `no_hops` int(10) unsigned NOT NULL,
  `no_inputs` int(10) unsigned DEFAULT NULL,
  `no_addresses` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`address`)
) ENGINE=InnoDB

1 个答案:

答案 0 :(得分:0)

您可以使用address_partitions表中的条件尝试子查询:

select b.address FROM (SELECT a.address FROM 
address_partitions as a 
WHERE a.npartition = 19) c
JOIN hop_addresses as b 
ON b.address=c.address;