博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mysql 的FIND_IN_SET函数慢的忧化
阅读量:6430 次
发布时间:2019-06-23

本文共 1334 字,大约阅读时间需要 4 分钟。

一个页面的查询,数据量不算太多,也不算太少,竟然用了10多秒

一、需求

    查找出卡片表里所包含的DIY卡片ID所对应的名字

 

二、sql 语句祥细信息

  SELECT cardName

     FROM diyCard

     WHERE FIND_IN_SET(id, ( SELECT group_concat(id) FROM card))

  diyCard表的数据量几千,card表的数据量几万

  原本SQL并没有这么少,这是分析后为了让大家能够更加明白的简易代码。

 

三、问题分析

  1)首先看一看索引加了没,没加,之后加了索引快了一些,但还是慢
  2)再观察代码
  最终把问题放在了FIND_IN_SET(id,(select group_concat(id) from card))
  仔细观察这段代码

  FIND_IN_SET是一个函数,里面的参数嵌套了一个子查询,意思就是说每次查找card表是否有diycard的id都可能是又运行了一次(select group_concat(id) from card),所以导致慢的根本原因。

  怎么办呢,想一想sql的执行顺序:

  1).首先执行 FROM 子句,从diycard表组装数据源(没问题)
  2).执行where子句,执行函数FIND_IN_SET,参数的数据源是(select group_concat(id) from card),就像上面说的每次查找diycard的id循环遍历都会运行(select group_concat(id) from card),在这里会消耗很多时间
  那么就从这里改造,把(select group_concat(id) from card)改成一个死数据一样,不让它每次去查数据库。
  注意把(select group_concat(id) from card)加到from后面,执行sql时直接组装数据源。还有这里的group_concat(id)让这个数据源只有一条记录,所以不会产生笛卡尔集。

四、解决问题
  

SELECT cardname    FROM diycard, ( SELECT group_concat(id) id FROM card) temp    WHERE   FIND_IN_SET(id, temp.card)

忧化sql的方法有很多
  1).索引的添加
  2).对于长sql,先删除部分不引响不慢的sql,再从剩余的sqll慢慢定位出效率低的sql
  3).多使用explain(可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们查询,让查询优化器能够更好的工作。)  

  。。。。。

文章作者介绍:

 

来自于小豹科技的田时伟-公司专注于软件基础研发平台,目前公司正在研发一款基于Netty的插件式的API网关-。 希望与对OpenAPI、微服务、API网关、Service Mesh等感兴趣的朋友多交流。 有兴趣的朋友请加QQ群244054462。

转载于:https://www.cnblogs.com/Tinsv/p/8316833.html

你可能感兴趣的文章
javascript中 for循环的一些写法 for length 以及for in 还有 for of 的区别
查看>>
java读取properties文件的几种方法
查看>>
Android初步-HelloWorld
查看>>
记录一下家里双路由实现wifi漫游功能
查看>>
统计字母个数
查看>>
论思维变通的重要性!--input输入框禁止编辑,且 右键弹出窗口复制
查看>>
【ocp-12c】最新Oracle OCP-071考试题库(43题)
查看>>
Vuex
查看>>
iOS深拷贝浅拷贝
查看>>
spring coud feign
查看>>
NPOI List数据源 导出excel
查看>>
07抽象类特点
查看>>
什么事数据对象以及属性分为什么类型?
查看>>
图论精炼500题
查看>>
递归,动态规划,找最短路径,Help Jimmy
查看>>
poj 1006 生理周期
查看>>
Leetcode题目:House Robber III
查看>>
生物技术制药课程学生论文调研报告集
查看>>
LNK1104 无法打开文件 exe
查看>>
二叉树中和为某一值的路径
查看>>