首页 > 解决方案 > SQL长查询优化

问题描述

试图弄清楚如何优化重要 SQL 查询的运行时。也许这里有一位专家可以帮助我解决这个问题。

我的 PHP -> Sql 查询:

    SELECT ws_manager_repl_log.*, kst_cs_shopping.thread_id, kst_cs_shopping.stage, kst_cs_shopping.user_id
    
    FROM ws_manager_repl_log 
    LEFT JOIN kst_cs_shopping ON ws_manager_repl_log.thread_id = kst_cs_shopping.thread_id
    
    WHERE 
       kst_cs_shopping.stage != 'shoping' 
       AND ws_manager_repl_log.updated_at <= 1599982332
       AND ws_manager_repl_log.mark_as_removed IS NULL
    
    ORDER BY ws_manager_repl_log.updated_at DESC LIMIT 15 OFFSET 15

这里有一个问题:

**Run Time: 4.206827**
Select Type Table   Type    Possible Keys   Key Key Len Ref Rows    Extra
SIMPLE  ws_manager_repl_log ALL                 415 Using where; Using temporary; Using filesort
SIMPLE  kst_cs_shopping ALL                 45831   Using where; Using join buffer (flat, BNL join)

运行时间很长......如何优化这样的查询?它有什么办法吗?感谢任何帮助。

画面一:https ://i.imgur.com/wF0du28.png

屏幕2:解释:https ://i.imgur.com/4lOhyso.png

屏幕 3:分析: https ://i.imgur.com/cU2SPgI.png

Screen4:索引定义:https ://i.imgur.com/UAfioBF.png

标签: phpmysqlsql

解决方案


首先, theLEFT JOIN是多余的,因为WHERE子句将它变成了INNER JOIN。表别名将使查询更易于编写和阅读:

SELECT mrl.*, s.thread_id, s.stage, s.user_id    
FROM ws_manager_repl_log mrl JOIN
     kst_cs_shopping s
     ON mrl.thread_id = s.thread_id    
WHERE s.stage <> 'shoping' AND
      mrl.updated_at <= 1599982332 AND
      mrl.mark_as_removed IS NULL    
ORDER BY mrl.updated_at DESC
LIMIT 15 OFFSET 15;

目前尚不清楚哪些索引最适合此。一种可能性是ws_manager_repl_log(mark_as_removed, updated_at, thread_id)kst_cs_shopping, thread_id, stage, user_id)

也就是说,还有其他可能性,但这个问题没有提供足够的信息。哪些过滤器(如果有)是最具选择性的?表之间是什么关系,1-1?1-n? n-1? 之前返回多少行limit


推荐阅读