简体   繁体   English

mysql查询需要很长时间

[英]mysql query is taking long time

my below query is taking more then 10 seconds. 我下面的查询需要10秒钟以上的时间。 How I can optimize this query. 我如何优化此查询。 Please suggest which field to add index. 请建议要添加索引的字段。 This query is drupal view for distance search. 该查询是用于距离搜索的drupal视图。

    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

I would recommend, that you learn about the PROCEDURE ANALYSE function of MySQL: http://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html 我建议您学习一下MySQL的PROCEDURE ANALYSE函数: http : //dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html

It will tell you which joins might not have an index they can use. 它会告诉您哪些联接可能没有可使用的索引。 From only looking at your query but without knowing the structure or data of the tables, we can't give you a good adivce. 仅查看查询而不了解表的结构或数据,就无法为您提供良好的选择。 Usually you should have an index on every column, you use in a JOIN and ORDER BY part of you query and you might have some indexes for the columns used in the WHERE clause. 通常,您应该在每个列上都有一个索引,在查询的JOIN和ORDER BY部分中使用,并且在WHERE子句中使用的列可能会有一些索引。

Here are some things to try immediately to see if you can improve performance. 这是一些可以立即尝试看看是否可以提高性能的方法。

  1. Try a compound index on the location table on (province, city, latitude, longitude, lid) . location表上(province, city, latitude, longitude, lid)尝试复合索引。 That compound index will, hopefully, accelerate the WHERE criteria computation for your locations. 该复合索引有望加快您所在位置的WHERE标准计算。
  2. Make sure your latitude and longitude columns have the FLOAT or DOUBLE data type. 确保您的latitudelongitude列具有FLOATDOUBLE数据类型。
  3. Try a compound index on the node table on (status, type, vid) . (status, type, vid)node表上尝试复合索引。 That index should help locate the exact node records in your WHERE clause and accelerate your joins. 该索引应有助于在WHERE子句中找到确切的node记录,并加快连接速度。
  4. Eliminate the spherical geometry computation from your WHERE clause. WHERE子句中消除球面几何计算。 You already have the bounding box range restriction, and you're already sorting by distance, so you shouldn't get too many extra locations this way. 您已经有边界框范围限制,并且已经按距离排序,因此您不应以这种方式获得过多的额外位置。 And, if you do, they shouldn't be too far away by a factor of more than 4/pi. 而且,如果这样做的话,它们的相距不应超过4 / pi。
  5. Can you get rid of the SELECT DISTINCT and just use SELECT ? 您可以摆脱SELECT DISTINCT而仅使用SELECT吗? Finding distinct values is a data-intensive operation. 查找不同的值是一项数据密集型操作。

For some helpful information on the distance computation and the bounding box optimization, please see this. 有关距离计算和边界框优化的一些有用信息,请参见此。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/ http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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