简体   繁体   English

MySQL查询优化避免文件排序

[英]MySql Query Optimization to avoid filesort

I would like someone to help me to optimize and avoid file sort in the following query. 我希望有人帮助我优化并避免在以下查询中进行文件排序。 Attached the screenshot of its explain 附上其说明的屏幕截图

SELECT DISTINCT(storages.id), 
     IF(admin_approve = 1 
           OR storage_free_auctions.user_id = 167 
           OR ISNULL(storage_free_auctions.user_id), 
        auction_date, NULL) AS auction_date1
FROM user_list_storage 
JOIN storages ON storages.id = user_list_storage.storage_id 
JOIN states ON states.id = storages.state 
LEFT JOIN storage_auctions ON storage_auctions.id = (
          SELECT storage_auctions.id FROM storage_auctions 
          LEFT JOIN storage_free_auctions 
          ON storage_free_auctions.storage_auctions_id=storage_auctions.id 
          WHERE storage_auctions.storage_id = storages.id 
          AND storage_auctions.status = 'Active' 
          AND (  ISNULL(storage_free_auctions.user_id) 
                 OR admin_approve = 1 
                 OR storage_free_auctions.user_id = 167) 
          AND CONCAT(auction_date,' ',start_time) >= CURDATE() 
          ORDER BY auction_date ASC LIMIT 1) 
LEFT JOIN storage_free_auctions 
     ON storage_free_auctions.storage_auctions_id=storage_auctions.id 
LEFT JOIN storage_auction_units 
     ON storage_auction_units.storage_auction_id = storage_auctions.id 
     AND storage_auction_units.status='Active' 
WHERE storages.storage_status = 'Active' 
AND user_list_storage.user_id = 167 
AND user_list_storage.user_list_id = 3 
AND (storage_free_auctions.user_id = 167 
     OR admin_approve = 1 
     OR ISNULL(storage_free_auctions.user_id) 
     OR user_list_storage.user_id = 167) 
GROUP BY storages.id 
order by auction_date1

First row of the explain result is as follows. 解释结果的第一行如下。

id : 1 Select_type : PRIMARY Table : user_list_storage Type : ref possible_keys : idx_user_list_id,idx_storage_id,idx_user_id key : idx_user_id key_len : 5 ref : const id: 1 Select_type: PRIMARY 表: user_list_storage 类型: ref 可能的 键: idx_user_list_id,idx_storage_id,idx_user_id 密钥: idx_user_id key_len: 5 ref: const
rows : 64 行: 64
Extra : Using where; 额外:在哪里使用; Using temporary; 使用临时; Using filesort 使用文件排序

Replace 更换

 LEFT JOIN storage_auctions 
        ON storage_auctions.id= (SELECT storage_auctions.id 
            FROM storage_auctions 
            LEFT JOIN storage_free_auctions 
                ON storage_free_auctions.storage_auctions_id = storage_auctions.id 
            WHERE storage_auctions.storage_id = storages.id 
              AND storage_auctions.status = 'Active' 
              AND (ISNULL(storage_free_auctions.user_id)
                    OR admin_approve = 1 
                    OR storage_free_auctions.user_id = 167) 
            AND CONCAT(auction_date,' ',start_time) >= CURDATE() ORDER BY auction_date ASC LIMIT 1) 

with

AND EXISTS (SELECT 1 
    FROM storage_auctions  
    WHERE storage_auctions.id = storages.id 
      AND CONCAT(auction_date,' ',start_time) >= CURDATE())

because your clauses in the left join are redundant and been done before, all you want there is that a record with the same id exists in the future, right? 因为您在左联接中的子句是多余的并且之前已经完成,所以您想要的是将来存在具有相同id的记录,对吗?

the rest of your joins are OK. 其余的联接都可以。 they are all based on integer columns, make sure that you index on all of these ids if they are not primary keys and runstats. 它们都基于整数列,如果它们不是主键和runstats,请确保对所有这些id进行索引。

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

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