I had pages that use location and views that were taking over 30 seconds to render. For example, see http://autism.healingthresholds.com/therapist/us/new-york/new-york/ny/all/25. That loads fast because I'm using boost cache to save the html. But for the initial page generation, devel says that there are multiple queries that take over 6 seconds. By indexing the location.latitude and location.longitude columns, I got the pageload time down an order of magnitude to 3 seconds. This was based on the advice to "add indexes for columns in a WHERE clause". When profiling, copying to tmp table dropped from 3.5 to 0.75 seconds.
Here's one of the hairy queries:
SELECT DISTINCT(node.nid) AS nid, node.title AS node_title, node.vid AS node_vid, node_data_field_body.field_body_value AS node_data_field_body_field_body_value, node_data_field_body.field_body_format AS node_data_field_body_field_body_format, node.type AS node_type, location.lid AS location_lid, node_data_field_list_image.field_list_image_fid AS node_data_field_list_image_field_list_image_fid, node_data_field_list_image.field_list_image_list AS node_data_field_list_image_field_list_image_list, node_data_field_list_image.field_list_image_data AS node_data_field_list_image_field_list_image_data, node_data_field_list_image.field_list_level_value AS node_data_field_list_image_field_list_level_value, node_data_field_list_featured.field_list_featured_value AS node_data_field_list_featured_field_list_featured_value, (IFNULL(ACOS(0.757556530858*COS(RADIANS(location.latitude))*(0.275695572132*COS(RADIANS(location.longitude)) + -0.961245000771*SIN(RADIANS(location.longitude))) + 0.652769563134*SIN(RADIANS(location.latitude))), 0.00000)*6368998.45727) AS location_targeted_proximity_sort FROM node node LEFT JOIN location_instance location_instance ON node.vid = location_instance.vid LEFT JOIN location location ON location_instance.lid = location.lid LEFT JOIN term_node term_node ON node.vid = term_node.vid AND term_node.tid = 3494 LEFT JOIN content_field_body node_data_field_body ON node.vid = node_data_field_body.vid LEFT JOIN content_type_listing node_data_field_list_image ON node.vid = node_data_field_list_image.vid LEFT JOIN content_type_listing node_data_field_list_featured ON node.vid = node_data_field_list_featured.vid WHERE (node.type in ('listing')) AND (node.status <> 0) AND (location.latitude > 40.3887981129 AND location.latitude < 41.1126858871 AND location.longitude > -74.474310416 AND location.longitude < -73.518749584) AND (term_node.tid IS NULL) GROUP BY nid ORDER BY node_data_field_list_featured_field_list_featured_value DESC, location_targeted_proximity_sort ASC
It's going through ~40 K listings nodes and finding the 30 that are closest to midtown New York. When I profiled the query, it reported "Showing rows 0 - 29 (1,503 total, Query took 3.5321 sec)". The step that dominated that time is "Copying to tmp table 3.499969".
I would suggest indexing the latitude and longitude columns by default. I'd also appreciate any other suggestions for further improving my query times.
Comments
Comment #1
yesct commentedHmmm how to propose this as a patch? Maybe as an update to be run when update.php runs?
Comment #2
ankur commentedI myself use database indices a lot, but am closing this due to lack of continuation and a lack of a patch.
My best guess is that the people that are running sites where this optimization is necessary probably just do it at the mysql command-line and don't think about it again.
But a patch would be nice :-)
Comment #3
ankur commented