开发者

MySQL spatial index doesn't work when equating MBRContains() to TRUE?

开发者 https://www.devze.com 2023-01-19 20:02 出处:网络
I have a SQL query that seems to be producing correct results but according to EXPLAIN isn\'t using the spatial index and so is taking much longer than necessary to return all the rows.

I have a SQL query that seems to be producing correct results but according to EXPLAIN isn't using the spatial index and so is taking much longer than necessary to return all the rows.

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

Interestingly, I figured out that if I remove the =true and let the MBRContains() stand alone, the spatial index gets used properly.

My question is: why is this the case, and can I do something to enable the spatial index to work even when I have =true written at the end of the WHERE clause?

And the only reason I have =true in there at all is because I'm using CodeIgniter's Active Record and can't see an easy w开发者_如何学编程ay around it (so if you know a way around it, that's another way of solving my problem). (Even switching to just use $this->db->query() would involve a lot of work.)

My table is like this:

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 ;

Thank you for your help!


I faced a similar problem while writing a query in hibernate. Here is how I worked around it: Hibernate and MySQL spatial index

All I did was register a new function with a tiny bit of hack in the MySQLDialect of our application:

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

And then I used this function in the HQL query. The query now became something like this:

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

which is valid HQL, and also generates SQL which makes use of the spatial index:

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

精彩评论

暂无评论...
验证码 换一张
取 消