php - 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
解决方案
首先, 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
?
推荐阅读
- javascript - 执行源自从 AJAX 加载的外部文件的脚本
- java - 编写一个 Java 程序来评估后缀表示法中的表达式 - 数据结构和算法类
- sql - 当表之间建立关系时,幕后发生了什么?
- c# - OLEDB 读取 Excel 文件在 IIS asp.net C# 上不起作用
- docker - jenkins ssh 管道插件不会与 docker run 挂断
- node.js - 使用原型继承函数调用时,tap.throws() 不起作用?
- bash - if [ -z "$SPARK_HOME" ]; 是什么意思 然后
- npm - 独立于其目录打包 npm 文件?
- javascript - 尝试填充我的用户模型并获得类型错误
- android - Android跨应用共享BottomNavigationView