3

Given is a table with 300'000 test-records.

I need to do a select like this:

SELECT (SQRT(POWER(ABS(posts.latitude-$lat),2)+POWER(ABS(posts.longitude-$lng),2))) AS distance
FROM table
ORDER BY distance
LIMIT 0,50

where $lat and $lng changes for every request. How could I possibly speed up such queries?

Thanks.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Raphael Jeger
  • 5,024
  • 13
  • 48
  • 79

2 Answers2

1

Actually you cannot optimize that query.

You are sorting the result using a calculated value, so you cannot use an index. If you use explain you could see how your query in being executed, and using temporary will be present in the extra column, which means that all the data from your query is being stored on a temporary table in which the ordering is performed.

It doesn't matter if you only want the first 50 matches in the query, it has first to get all the data, dump it into a temporary table, sort the result in that table and then return to you the first 50 matches.

As you can suppose, this is a time and memory consuming operation.

So you best option is to place an index in the table to get all the rows you need as fast as you can and then process them with php to get the data you need.

By the way, have a look to MySQL optimization guide.

Ander2
  • 5,569
  • 2
  • 23
  • 42
  • 1
    So, your suggestion is to add an index? Or send the 300k rows to PHP (or whatever the OP is using, there are many languages out there, not only php) and do the calculations there? – ypercubeᵀᴹ Mar 09 '13 at 14:24
  • The suggestion is to add one (or more) index to filter as much data as it could, and then send all that data to PHP and do the calculation and sorting there (using arrays). – Ander2 Mar 09 '13 at 14:28
  • What query are you suggesting to use for the filtering? – ypercubeᵀᴹ Mar 09 '13 at 14:40
  • Nothing for this query ( there are no `where` conditions ). – Ander2 Mar 09 '13 at 14:43
  • So, if he keeps this query, which will return maximum 50 rows, what is the need for the PHP sorting? – ypercubeᵀᴹ Mar 09 '13 at 14:44
  • Read the answer again. Before he gets the 50 rows, mysql has to get ALL the rows, store them in a temporary table, do the sorting and then return the first 50 ones. Performing the sorting and processing in PHP will be faster. – Ander2 Mar 09 '13 at 14:46
  • I agree with that, 100% (that this MySQL query will be slow) and for your reasoing. But what you propose as an alternative is not clear. Not clear at all. – ypercubeᵀᴹ Mar 09 '13 at 14:54
  • Well, the query cannot be optimized, so his only chance is to process the data himself. From my experience, sorting big tables without indexes in mysql could be very very slow. – Ander2 Mar 09 '13 at 14:57
  • 3
    Well, I can't really understand why you think that PHP will do the sorting faster. It's going to be equally slow. PHP cannot magically sort 300k rows. – ypercubeᵀᴹ Mar 09 '13 at 15:00
  • Just made a local example with an int's array and it takes less than a second ordering 300.000 elements. Fiddle example: http://phpfiddle.org/main/code/c6v-hyx – Ander2 Mar 09 '13 at 15:22
-1

Make the column for $userParam an index, that way the query will perform faster. Or you could create an indexed view: http://www.codeproject.com/Articles/199058/SQL-Server-Indexed-Views-Speed-Up-Your-Select-Quer

Hope this helps

Crowlix
  • 1,269
  • 9
  • 19