Mysql 在左JOIN的ON子句中使用BETWEEN不';不要使用任何索引

Mysql 在左JOIN的ON子句中使用BETWEEN不';不要使用任何索引,mysql,indexing,left-join,between,Mysql,Indexing,Left Join,Between,我正在通过shop\u id选择单元格,另外,我想知道在单元格的定义区域内有多少个镜头。这些是wgs84坐标,但因为我没有把格林坐标和本初子午线重叠,所以我不必在意。所以我试着在on子句中使用两个中间语句 只要我使用一个内部连接,它就工作得非常好。但是我也需要那些没有任何take的单元格,所以我后来切换到LEFT JOIN: SELECT `cell`.*, COUNT(take.take_id) FROM `cell` LEFT JOIN `take` ON (take.take_l

我正在通过
shop\u id
选择
单元格
,另外,我想知道在
单元格
的定义区域内有多少个
镜头
。这些是wgs84坐标,但因为我没有把格林坐标和本初子午线重叠,所以我不必在意。所以我试着在on子句中使用两个中间语句

只要我使用一个内部连接,它就工作得非常好。但是我也需要那些没有任何take的单元格,所以我后来切换到LEFT JOIN:

SELECT `cell`.*, COUNT(take.take_id)
FROM `cell`
LEFT JOIN `take` ON 
    (take.take_lat BETWEEN cell.cell_lat_south AND cell.cell_lat_north) AND
    (take.take_lon BETWEEN cell.cell_lon_west AND cell.cell_lon_east)
WHERE (cell.shop_id = '1')
GROUP BY `cell`.`cell_id`
我得到了预期的结果,但执行它需要1分钟以上,而不是1秒以下(与内部联接一样)。这只涉及到约3000个细胞

解释SELECT查询结果时不使用我在所有坐标列上放置的任何索引:

+----+-------------+-------+------------+------+----------------------------------------------+---------+---------+-------+--------+----------+------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys                                | key     | key_len | ref   | rows   | filtered | Extra                                          |
+----+-------------+-------+------------+------+----------------------------------------------+---------+---------+-------+--------+----------+------------------------------------------------+
|  1 | SIMPLE      | cell  | NULL       | ref  | PRIMARY,shop_id,cell_lat_south,cell_lon_west | shop_id | 4       | const |   2936 |   100.00 | Using index condition                          |
|  1 | SIMPLE      | take  | NULL       | ALL  | take_lat                                     | NULL    | NULL    | NULL  | 136822 |   100.00 | Range checked for each record (index map: 0x4) |
+----+-------------+-------+------------+------+----------------------------------------------+---------+---------+-------+--------+----------+------------------------------------------------+
最后,我尝试了一个将联接替换为子查询的查询:

SELECT `cell`.*, (
    SELECT COUNT(*)
    FROM `take`
    WHERE
        take.take_lat BETWEEN cell.cell_lat_south AND cell.cell_lat_north AND
        take.take_lon BETWEEN cell.cell_lon_west AND cell.cell_lon_east)
    as `take_count`
FROM `cell`
WHERE (cell.shop_id = '1')
这将产生正确的结果,并且查询再次快速。但奇怪的是在解释中,现在显示的是
filtered
at
1.23
,而不是之前的
100
。仍然没有使用索引:

+----+--------------------+-------+------------+------+---------------+---------+---------+-------+--------+----------+------------------------------------------------+
| id | select_type        | table | partitions | type | possible_keys | key     | key_len | ref   | rows   | filtered | Extra                                          |
+----+--------------------+-------+------------+------+---------------+---------+---------+-------+--------+----------+------------------------------------------------+
|  1 | PRIMARY            | cell  | NULL       | ref  | shop_id       | shop_id | 4       | const |   2936 |   100.00 | NULL                                           |
|  2 | DEPENDENT SUBQUERY | take  | NULL       | ALL  | take_lat      | NULL    | NULL    | NULL  | 136822 |     1.23 | Range checked for each record (index map: 0x4) |
+----+--------------------+-------+------------+------+---------------+---------+---------+-------+--------+----------+------------------------------------------------+
这些表如下所示:

单元格
约450k行

cell_id | shop_id | cell_lat_north | cell_lat_south | cell_lon_west | cell_lon_east
-----------------------------------------------------------------------------------
1       | 1       | 54.858601      | 54.849621      | 14.074777     | 14.089339    
2       | 1       | 54.858601      | 54.849621      | 14.089339     | 14.103901    
3       | 2       | 54.858601      | 54.849621      | 14.103901     | 14.118464    
获取约130k行的

take_id | take_lat       | take_lon
------------------------------------
1       | 54.851234      | 14.081234
2       | 54.851234      | 14.081234

我看不到解释哪些列有索引?您可以添加运行更快的内部联接查询吗?请在
take
上提供
SHOW CREATE TABLE
EXPLAIN FORMAT=JSON SELECT…
INDEX(take_lat,take_lon)
。我看不到说明哪些列具有索引?您可以添加运行更快的内部联接查询吗?请在
take
上提供
SHOW CREATE TABLE
EXPLAIN FORMAT=JSON SELECT…
索引(take_lat,take_lon)
take_id | take_lat       | take_lon
------------------------------------
1       | 54.851234      | 14.081234
2       | 54.851234      | 14.081234
CREATE TABLE take (
     take_id int(11) NOT NULL AUTO_INCREMENT,
     take_lat float(10,6) NOT NULL,
     take_lon float(10,6) NOT NULL,
     PRIMARY KEY (take_id),
     KEY shop_id (shop_id),
     KEY take_lat (take_lat,take_lon)
) ENGINE=InnoDB DEFAULT CHARSET=utf8