мой запрос ниже занимает более 10 секунд. Как я могу оптимизировать этот запрос. Пожалуйста, предложите, в какое поле добавить индекс.
Этот запрос представляет собой друпальный вид для дистанционного поиска.
SELECT DISTINCT location.lid AS location_lid, node.nid AS nid, location.name AS location_name, location_phone.phone AS location_phone_phone, location_fax.fax AS location_fax_fax, node.title AS node_title, node.language AS node_language, location.additional AS location_additional, location.city AS location_city, location.latitude AS location_latitude, location.longitude AS location_longitude, location.country AS location_country, location.postal_code AS location_postal_code, location.province AS location_province, location.street AS location_street, field_data_field_showroom_level.field_showroom_level_value AS field_data_field_showroom_level_field_showroom_level_value, field_data_field_showroom_type.field_showroom_type_value AS field_data_field_showroom_type_field_showroom_type_value, field_data_field_showroom_inventory_records.field_showroom_inventory_records_value AS field_data_field_showroom_inventory_records_field_showroom_i, field_data_field_record_type_id.field_record_type_id_value AS field_data_field_record_type_id_field_record_type_id_value, field_data_field_toto_gallery.field_toto_gallery_value AS field_data_field_toto_gallery_field_toto_gallery_value, 'node' AS field_data_field_showroom_location_node_entity_type, 'node' AS field_data_field_day_of_operation_node_entity_type, 'node' AS field_data_field_day_of_operation_comments_node_entity_type, 'node' AS field_data_field_showroom_open_node_entity_type, 'node' AS field_data_field_showroom_close_node_entity_type, 'node' AS field_data_field_appointment_needed_node_entity_type, (COALESCE(ACOS(0.83308162381476*COS(RADIANS(location.latitude))*(0.098658826854837*COS(RADIANS(location.longitude)) + -0.99512131716873*SIN(RADIANS(location.longitude))) + 0.55315007734083*SIN(RADIANS(location.latitude))), 0.00000)*6371570.9190939) AS location_distance, 'node' AS field_data_field_salesforce_id_node_entity_type, 'node' AS field_data_field_multiple_product_sku_node_entity_type, 'node' AS field_data_field_product_types_node_entity_type, 'node' AS field_data_field_toto_gallery_node_entity_type, 'node' AS field_data_field_showroom_level_node_entity_type
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
INNER JOIN field_data_field_toto_gallery field_data_field_toto_gallery ON node.nid = field_data_field_toto_gallery.entity_id AND (field_data_field_toto_gallery.entity_type = 'node' AND field_data_field_toto_gallery.deleted = '0')
LEFT JOIN field_data_field_multiple_product_sku field_data_field_multiple_product_sku ON node.nid = field_data_field_multiple_product_sku.entity_id AND (field_data_field_multiple_product_sku.entity_type = 'node' AND field_data_field_multiple_product_sku.deleted = '0')
LEFT JOIN location_phone location_phone ON location_instance.lid = location_phone.lid
LEFT JOIN location_fax location_fax ON location_instance.lid = location_fax.lid
LEFT JOIN field_data_field_showroom_level field_data_field_showroom_level ON node.nid = field_data_field_showroom_level.entity_id AND (field_data_field_showroom_level.entity_type = 'node' AND field_data_field_showroom_level.deleted = '0')
LEFT JOIN field_data_field_showroom_type field_data_field_showroom_type ON node.nid = field_data_field_showroom_type.entity_id AND (field_data_field_showroom_type.entity_type = 'node' AND field_data_field_showroom_type.deleted = '0')
LEFT JOIN field_data_field_showroom_inventory_records field_data_field_showroom_inventory_records ON node.nid = field_data_field_showroom_inventory_records.entity_id AND (field_data_field_showroom_inventory_records.entity_type = 'node' AND field_data_field_showroom_inventory_records.deleted = '0')
LEFT JOIN field_data_field_record_type_id field_data_field_record_type_id ON node.nid = field_data_field_record_type_id.entity_id AND (field_data_field_record_type_id.entity_type = 'node' AND field_data_field_record_type_id.deleted = '0')
WHERE (( (node.status = '1')
AND (node.type IN ('showrooms'))
AND (location.latitude > '32.859795378699'
AND location.latitude < '34.306986221301'
AND location.longitude > '-85.206632058424'
AND location.longitude < '-83.469478341576')
AND ((COALESCE(ACOS(0.83308162574562*COS(RADIANS(location.latitude))*(0.098658823381208*COS(RADIANS(location.longitude)) + -0.99512131751311*SIN(RADIANS(location.longitude))) + 0.55315007443282*SIN(RADIANS(location.latitude))), 0.00000)*6371570.9191628) < '80467.35')
AND (location.province = 'GA')
AND (location.city LIKE 'Atlanta' ESCAPE '\\') )
AND( (field_data_field_toto_gallery.field_toto_gallery_value = '1')
OR (field_data_field_multiple_product_sku.field_multiple_product_sku_value NOT LIKE 'NULL' ESCAPE '\\') ))
ORDER BY field_data_field_showroom_level_field_showroom_level_value DESC,
field_data_field_showroom_type_field_showroom_type_value DESC,
location_distance ASC,
field_data_field_showroom_inventory_records_field_showroom_i DESC,
field_data_field_record_type_id_field_record_type_id_value ASC,
field_data_field_toto_gallery_field_toto_gallery_value DESC
LIMIT 10 OFFSET 0
Я бы порекомендовал, чтобы вы узнали о PROCEDURE ANALYSE
функция MySQL: http://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html
Он скажет вам, какие объединения могут не иметь индекса, который они могут использовать. Мы не можем дать вам хорошее представление, только глядя на ваш запрос, но не зная структуры или данных таблиц. Обычно у вас должен быть индекс для каждого столбца, вы используете в запросе JOIN и ORDER BY часть, и у вас могут быть некоторые индексы для столбцов, используемых в предложении WHERE.
Вот несколько вещей, которые нужно попробовать немедленно, чтобы увидеть, если вы можете улучшить производительность.
location
стол на (province, city, latitude, longitude, lid)
, Надеемся, что этот составной индекс ускорит WHERE
Расчет критериев для вашего местоположения. latitude
а также longitude
столбцы имеют FLOAT
или же DOUBLE
тип данных.node
стол на (status, type, vid)
, Этот индекс должен помочь найти точное node
записи в вашем WHERE
оговорка и ускорить ваши соединения.WHERE
пункт. У вас уже есть ограничение диапазона ограничивающего прямоугольника, и вы уже сортируете по расстоянию, поэтому вы не должны получать слишком много дополнительных мест таким образом. И, если вы это сделаете, они не должны быть слишком далеко с коэффициентом более 4 / пи.SELECT DISTINCT
и просто использовать SELECT
? Поиск различных значений является интенсивной операцией с данными. Для получения некоторой полезной информации о расчете расстояния и оптимизации ограничительной рамки, пожалуйста, смотрите это. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/