Переписать этот подзапрос? - PullRequest
1 голос
/ 05 октября 2010

Я пытаюсь построить новую таблицу так, чтобы значения в существующей таблице НЕ содержались (но, очевидно, следующие проверки на наличие) в другой таблице.Ниже приведена структура моей таблицы:

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              | 
+----+--------------------+--------------------+-------+-------------------+-----------+---------+------+------+--------------------------+

Для выполнения запроса требуется 6 секунд1000 записей в т1, что для меня неприемлемо.Как я могу переписать этот запрос, используя Joins (или, возможно, более быстрый способ, если таковой существует), если у меня нет столбца для присоединения?Я полагаю, что даже хранимая процедура приемлема в худшем случае.Моя цель, наконец, создать новую таблицу, содержащую записи из t1.Есть предложения?

Ответы [ 2 ]

1 голос
/ 05 октября 2010

Если оптимизатор запросов не работает, конструкция 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 ;

0 голосов
/ 05 октября 2010

Это похоже на случай, когда снятие с нуля t1 может быть полезным.Добавление столбца GeomFrmTxt со значением GeomFromText(CONCAT('POINT(', t1.point, ' 0)')) может ускорить запрос, который у вас уже есть.

...