MySQL空间索引在将MBRContains()等于TRUE时无效?

4

我有一个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()单独存在,空间索引就会被正确使用。
我的问题是:为什么会这样,即使在WHERE子句的结尾加上=true,我能不能做些事情来启用空间索引?
而我之所以加上=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 ;

感谢您的帮助!

你如何获取表的规格? - user4951
@JimThio,我不明白你在问什么,但请参考http://dev.mysql.com/doc/refman/5.0/en/explain.html。 - Ryan
假设你有一张表。如何使用phpmyadmin来显示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(1 ... 等等的内容。 - user4951
1
@JimThio,在左侧面板中,单击您想要架构的表,然后单击其导出选项卡,接着取消数据复选框,最后单击“Go”。 - Ryan
1个回答

0

在使用Hibernate编写查询时,我遇到了类似的问题。这是我解决它的方法:Hibernate和MySQL空间索引

我所做的就是在我们应用程序的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 ...

我并没有验证这是否会对我有所帮助,因为我的问题已经几年了,而且我也不再从事这方面的工作,但它似乎是最好的答案(因为它是唯一的!)。谢谢。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接