我正在尝试构建一个新表,以便在另一个表中不包含现有表中的值(但显然包含以下检查)。以下是我的表结构:
mysql> explain t1;
+-----------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| point | bigint(20) unsigned | NO | MUL | 0 | |
+-----------+---------------------+------+-----+---------+-------+
mysql> explain whitelist;
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| x | bigint(20) unsigned | YES | | NULL | |
| y | bigint(20) unsigned | YES | | NULL | |
| geonetwork | linestring | NO | MUL | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
我的查询如下:
SELECT point
FROM t1
WHERE EXISTS(SELECT source
FROM whitelist
WHERE MBRContains(geonetwork, GeomFromText(CONCAT('POINT(', t1.point, ' 0)'))));
说明:
+----+--------------------+--------------------+-------+-------------------+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+--------------------+-------+-------------------+-----------+---------+------+------+--------------------------+
| 1 | PRIMARY | t1 | index | NULL | point | 8 | NULL | 1001 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | whitelist | ALL | _geonetwork | NULL | NULL | NULL | 3257 | Using where |
+----+--------------------+--------------------+-------+-------------------+-----------+---------+------+------+--------------------------+
查询在t1中执行1000条记录需要6秒钟,这对我来说是不可接受的。如果我没有要加入的列,如何使用连接重写此查询(或者如果存在的话,可能是更快的方式)?在最坏的情况下,即使是存储过程也是可以接受的。我的目标是最终创建一个包含来自t1的条目的新表。有什么建议吗?
答案 0 :(得分:1)
除非查询优化器失败,否则WHERE EXISTS
构造应该与具有GROUP
子句的连接产生相同的计划。看看优化MBRContains(geonetwork, GeomFromText(CONCAT('POINT(', t1.point, ' 0)'))))
,这可能是您的查询一直花费的地方。我没有这方面的建议,但这是用JOIN
编写的查询:
Select t1.point
from t1
join whitelist on MBRContains(whitelist.geonetwork, GeomFromText(CONCAT('POINT(', t1.point, ' 0)'))))
group by t1.point
;
或者让t1中的点不在白名单中:
Select t1.point
from t1
left join whitelist on MBRContains(whitelist.geonetwork, GeomFromText(CONCAT('POINT(', t1.point, ' 0)'))))
where whitelist.id is null
;
答案 1 :(得分:0)
这似乎是对t1
进行去正规化可能有益的情况。添加值为GeomFrmTxt
的{{1}}列可以加快您已有的查询速度。