简体   繁体   中英

Optimizing Sqlite query for INDEX

I have a table of 320000 rows which contains lat/lon coordinate points. When a user selects a location my program gets the coordinates from the selected location and executes a query which brings all the points from the table that are near. This is done by calculating the distance between the selected point and each coordinate point from my table row. This is the query I use:

select street from locations 
where (  ( (lat - (-34.594804)) *(lat - (-34.594804)) ) + ((lon - (-58.377676 ))*(lon - (-58.377676 ))) <= ((0.00124)*(0.00124))) 
group by street;

As you can see the WHERE clause is a simple Pythagoras formula to calculate the distance between two points. Now my problem is that I can not get an INDEX to be usable. I've tried with

CREATE INDEX indx ON location(lat,lon) 

also with

CREATE INDEX indx ON location(street,lat,lon) 

with no luck. I've notice that when there is math operation with lat or lon, the index is not being called . Is there any way I can optimize this query for using an INDEX so as to gain speed results?

Thanks in advance!

The problem is that the sql engine needs to evaluate all the records to do the comparison (WHERE ..... <= ...) and filter the points so the indexes don't speed up the query. One approach to solve the problem is compute a Minimum and Maximum latitude and longitude to restrict the number of record. Here is a good link to follow: Finding Points Within a Distance of a Latitude/Longitude

Did you try adjusting the page size ? A table like this might gain from having a different (ie the largest?) available page size.

PRAGMA page_size = 32768;

Or any power of 2 between 512 and 32768. If you change the page_size, don't forget to vacuum the database (assuming you are using SQLite 3.5.8. Otherwise, you can't change it and will need to start a fresh new database).

Also, running the operation on floats might not be as fast as running it on integers (big maybe), so that you might gain speed if you record all your coordinates times 1 000 000.

Finally, euclydian distance will not yield very accurate proximity results. The further you get from the equator, the more the circle around your point will flatten to ressemble an ellipse. There are fast approximations which are not as calculation intense as a Great Circle Distance Calculation (avoid at all cost!)

You should search in a square instead of a circle. Then you will be able to optimize.

Surely you have a primary key in locations? Probably called id?

Why not just select the id along with the street?

select id, street from locations 
where (  ( (lat - (-34.594804)) *(lat - (-34.594804)) ) + ((lon - (-58.377676 ))*(lon - (-58.377676 ))) <= ((0.00124)*(0.00124))) 
group by street;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM