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
at1.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