xingkong0128 2024-06-12 06:25 采纳率: 0%
浏览 3

mysql in 查询效率的奇葩问题

mysql in 查询效率问题

问题如下, 现有2个sql

第一个如下: 查询返回 50 条, 查询时间 150ms

 select
    t1.id,
    t1.order_no,
    t1.status,
    t1.company_id,
    t1.company_name,
    t1.dept_id,
    t1.dept_name,
    t1.room_id,
    t1.room_name,
    t1.doctor_id,
    t1.doctor_name,
    t1.medical_id,
    t1.medical_name,
    t1.medical_number,
    t1.is_transfer,
    t1.doctor_id_before,
    t1.doctor_name_before,
    t1.sign_time,
    t2.ref_type
from
    dts_treatment_order t1,
    dts_treatment_doctor_ref t2
where
    t1.id = t2.ref_order_id
    
    and t2.ref_doctor_id = 1800337755708911618
    and t1.plan_day = 1718121600000         
    and t1.company_id = 1787320614174867457
and t1.status in ('SIGNED')
    and t1.is_delete = 'N'
          
order by

    gmt_modify desc

第二个如下:
在 in 条件中随意加一个字符 , 查询速度 为 15ms 左右, 提升了10倍
不知是何原因造成的,

 select
    t1.id,
    t1.order_no,
    t1.status,
    t1.company_id,
    t1.company_name,
    t1.dept_id,
    t1.dept_name,
    t1.room_id,
    t1.room_name,
    t1.doctor_id,
    t1.doctor_name,
    t1.medical_id,
    t1.medical_name,
    t1.medical_number,
    t1.is_transfer,
    t1.doctor_id_before,
    t1.doctor_name_before,
    t1.sign_time,
    t2.ref_type
from
    dts_treatment_order t1,
    dts_treatment_doctor_ref t2
where
    t1.id = t2.ref_order_id
    
    and t2.ref_doctor_id = 1800337755708911618
    and t1.plan_day = 1718121600000         
    and t1.company_id = 1787320614174867457
and t1.status in ('SIGNED', 'xxxx')    
    and t1.is_delete = 'N'
          
order by

    gmt_modify desc
    
;    
    

展开全部

  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2024-06-12 06:25
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    MySQL 中 IN 子句的效率问题通常与几个因素有关:

    1. 索引使用:如果 IN 子句中的值能够利用到索引,查询效率会更高。如果 IN 子句中的值没有索引支持,MySQL 需要进行全表扫描。

    2. 查询优化器:MySQL 的查询优化器可能会根据 IN 列表中的值的数量和分布来选择不同的查询计划。如果 IN 列表中只有一个值,优化器可能会认为使用索引不如全表扫描高效。

    3. 值的分布:如果 IN 子句中的值在数据表中的分布不均匀,这可能影响查询的效率。

    在你提供的例子中,当 IN 子句中只有一个值 'SIGNED' 时,查询效率较低可能是因为:

    • 优化器认为使用索引不如全表扫描高效。
    • 'SIGNED' 这个值在 t1.status 列中可能非常常见,使得索引的优势不明显。

    而当你在 IN 子句中添加了 'xxxx' 这个值之后,查询速度显著提升可能是因为:

    • 优化器重新评估了查询计划,可能认为使用索引更高效。
    • 添加的 'xxxx' 值可能让优化器认为这个 IN 列表不太可能全部匹配,因此更倾向于使用索引来快速排除不匹配的行。

    要解决这个问题,你可以尝试以下几种方法:

    • 确保索引:确保 t1.status 列上有有效的索引,并且这个索引能够被 IN 子句中的值所利用。

    • 分析查询:使用 EXPLAINEXPLAIN EXTENDED 来分析查询的执行计划,看看优化器是如何决定查询策略的。

    • 调整 IN 子句:尝试使用不同的值或者值的组合,看看是否能够触发更优的查询计划。

    • 考虑使用 FIND_IN_SET():如果 IN 子句中的值是固定的,并且数量不多,可以考虑将这些值存储在一个字符串中,并使用 FIND_IN_SET() 函数来替代 IN 子句。

    • 数据库版本:确保你使用的 MySQL 版本是最新的,或者至少是性能改进过的版本,因为不同版本的 MySQL 在查询优化上可能有所不同。

    关于参考资料,你可以查看 MySQL 官方文档中关于 IN 子句和查询优化的部分,或者搜索一些数据库性能优化的教程和博客文章。由于我无法提供具体的网址,建议你使用搜索引擎查找相关的资料。

    如果你需要进一步的帮助,比如具体的代码实现或者更详细的分析,请提供更多的信息,我会尽力帮助你。

    评论 编辑记录
编辑
预览

报告相同问题?

问题事件

  • 修改了问题 6月12日
  • 创建了问题 6月12日

悬赏问题

  • ¥30 silcavo仿真,30分钟,只需要代码
  • ¥15 FastReport 怎么实现打印后马上关闭打印预览窗口
  • ¥15 利用3支股票数据估计其均值和方差的95%置信区间。
  • ¥15 微信小程序运行一项功能时,弹出未知错误弹框,检查代码没有问题
  • ¥15 ATAC测序生成self-pseudo replicates之前是否要进行去线粒体reads
  • ¥15 python模糊字匹配函数问题
  • ¥20 谁刷目标页面的uv记录器上数据,数据只记录跳转的数值
  • ¥30 数据库软件的安装方法
  • ¥15 一道以太网数据传输题
  • ¥15 python 下载群辉文件