2

Hello i have a a question.

I have a Table where the time is an index. My select statement look like this :

select count(*) from sometable
   where
      time between @startTime and @endTime
      and
      st_intersects(location,@somePolygon);

this Query takes 60 seconds to run. The table contains more then 50 million rows so i think it is okay. But now if i add location as and Index the Query takes 90 seconds to run. Why is it slowing down ? instead of speeding up ?

//Update Hello thanks four the feedback.

Explain with Index

 id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows    | filtered | Extra
  1 | SIMPLE      | q1_geo | NULL       | range | ORT, Zeit     | Zeit |       5 | NULL | 6454092 |   100.00 | Using index condition; Using where

and without

id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows    | filtered | Extra
 1 | SIMPLE      | q1_geo | NULL       | range | Zeit          | Zeit |       5 | NULL | 6454092 |   100.00 | Using index condition; Using where

//Update

Version : '5.7.5-m15' Engien : MyISAM

Table, Create Table

CREATE TABLE `q1_geo` (
  `ID` int(11) NOT NULL,
  `ZEIT` datetime NOT NULL,
  `R_ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `ORT` point NOT NULL,
  PRIMARY KEY (`ID`,`ZEIT`,`R_ID`),
  KEY `Zeit` (`ZEIT`),
  KEY `Ort` (`ORT`(25))
) ENGINE=MyISAM AUTO_INCREMENT=842057641 DEFAULT CHARSET=latin1
3
  • Please post the EXPLAIN results of your query with and without the location index. Commented Jan 16, 2016 at 13:28
  • What other important queries do you have? A solution for this query may hurt others. Commented Jan 16, 2016 at 16:05
  • Potentially relevant here are your server version (SELECT @@VERSION;) and storage engine ENGINE=MyISAM || ENGINE=InnoDB in the table definition. Add the output of SHOW CREATE TABLE ... please. Commented Jan 17, 2016 at 0:15

1 Answer 1

2

You're hitting an interesting problem in MySQL indexing here. When you use the simple index on time your query does a range scan on that index, then it computes st_intersects() for each row in that range.

But, when you add a second geo index on location MySQL's query planner probably (post your EXPLAIN! Post your table definitions!) does two index scans and then an index merge.

You can't make a compound index of a geo and an ordinary column.

Another thing you'll need to know to speed up this query is whether your time criterion or your spatial criterion is more selective. Which one winnows down your set of data to fewer results? That's the one you want to index first.

How do you fix this? If you can break out your location geo variable into two separate columns (they might be x and y, or lat and long), then put the time, x and y into a compound index, then do something like this:

WHERE  time >= @startTime
  AND  time <= @endTime
  AND  x >= MinX(@polygon)
  AND  x <= MaxX(@polygon)
  AND  y >= MinY(@polygon)
  AND  y <= MaxY(@polygon)
  AND  st_intersects(location, @somePolygon)

You'll need to work out the Min and Max functions on your polygon parameters.

The point of this trick is to allow you to put some if not all your spatial information into an ordinary compound index instead of into a standalone geo index.

Sign up to request clarification or add additional context in comments.

1 Comment

I put Explain statements in the Question :) Thanks for the answers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.