Solved

Improving a query (peformance)

Posted on 2013-01-30
3
281 Views
Last Modified: 2013-01-30
Hello,

I have the following query (great circle computation):

SELECT id, city_name, ( 6371 * acos( cos( radians(37.102528) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(25.376093) ) + sin( radians(37.102528) ) * sin( radians( lat ) ) ) ) AS distance
FROM city_names HAVING distance < 25 OR distance IS NULL ORDER BY distance LIMIT 0 , 200;

My table has about 15M records and this query takes from 13 to 22 sec to execute. I have an index on lat and long fields (both fields on the same index).

Are there any ways to improve the speed of this query?
0
Comment
Question by:infodigger
3 Comments
 
LVL 10

Assisted Solution

by:deviprasadg
deviprasadg earned 166 total points
ID: 38834299
create materialized view with the above query for sharp increase in performance of the select statement.

http://stackoverflow.com/questions/2534506/how-to-implement-materialized-view-with-mysql
0
 
LVL 7

Accepted Solution

by:
Beneford earned 167 total points
ID: 38834307
Do you have a small number of locations from which the distance is calculated?
If so, an additional column in the table for each destination would allow you to pre-calculate (in 22s) and then run the calculation.

If there are multiple centre points, you should see an improvement by:
1. Precalculate radians ( fixed-value ) - just multiply by pi/180.
2. Precalculate sin(radians(lat)) - (same for cos and lng) and store the values in the table
3. Move the Earth-size multiplier (6371) into the having clause: HAVING distance < 25/6371

Note: if you're looking at small distances, you may want to use the Haversine formula, but that may not be quicker.

Better (but I have no experience of it) might be the MySQL 5 Spacial Extensions - http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html.
0
 
LVL 25

Assisted Solution

by:Tomas Helgi Johannsson
Tomas Helgi Johannsson earned 167 total points
ID: 38834787
Hi!

For this query to have optimal performance you should create an index like this
CREATE INDEX city_dist_ix ON TABLE city_names (lat,long, city_name,id)  USING BTREE;

This will make the query index only query and hopefully a little bit faster. :)

Regards,
     Tomas Helgi
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question