将MBRContains()等同为TRUE时,MySQL空间索引不起作用?

时间:2010-10-08 23:38:37

标签: mysql

我有一个SQL查询似乎产生了正确的结果但是根据EXPLAIN没有使用空间索引,因此返回所有行所需的时间要长得多。

SELECT * FROM listings2
WHERE MBRContains(    GeomFromText('POLYGON((32.653132834095 -117.40548330929, 32.653132834095 -117.06151669071, 32.942267165905 -117.06151669071,32.942267165905 -117.40548330929,32.653132834095 -117.40548330929)    )')  ,geoPoint)=true

有趣的是,我发现如果我删除=true并让MBRContains()独立,空间索引就会被正确使用。

我的问题是:为什么会出现这种情况,即使我在=true子句的末尾写了WHERE,我还能做些什么来使空间索引能够正常工作吗?

我在那里=true的唯一原因是因为我正在使用CodeIgniter的Active Record并且看不到它的简单方法(所以如果你知道解决方法,这是解决我的问题的另一种方式。)(即使转换为仅使用$this->db->query()也需要做很多工作。)

我的表是这样的:

CREATE TABLE IF NOT EXISTS `listings2` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(255) NOT NULL DEFAULT '',
      `latitude` decimal(10,6) NOT NULL,
      `longitude` decimal(10,6) NOT NULL,
      `geoPoint` point NOT NULL,
      PRIMARY KEY (`id`),
      KEY `latitude` (`latitude`),
      KEY `longitude` (`longitude`),
      SPATIAL KEY `geoPoint` (`geoPoint`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=404838 ;

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我在hibernate中编写查询时遇到了类似的问题。以下是我解决这个问题的方法:Hibernate and MySQL spatial index

我所做的只是在我们的应用程序的MySQLDialect中注册了一个带有一点点黑客的新函数:

registerFunction("mbr_contains", new SQLFunctionTemplate(Hibernate.BOOLEAN, "MBRContains(?1, ?2) and 1"));

然后我在HQL查询中使用了这个函数。查询现在变成了这样的:

... and mbr_contains(GeomFromText(:${boundaryVariable}), location) = 1 ...

是有效的HQL,并且还生成使用空间索引的SQL:

... and MBRContains(GeomFromText(?), location) and 1 = 1 ...