当我的查询在“IN”子句中有大量值时,MySQL 不使用我期望的索引

2023-11-30

我遇到问题时IN子句包含太多值。考虑这个查询

EXPLAIN
SELECT DISTINCT t.entry_id , t.sticky , wd.field_id_104 , t.title
FROM exp_channel_titles AS t
LEFT JOIN exp_channels ON t.channel_id = exp_channels.channel_id
LEFT JOIN exp_channel_data AS wd ON t.entry_id = wd.entry_id
LEFT JOIN exp_members AS m ON m.member_id = t.author_id
INNER JOIN exp_category_posts ON t.entry_id = exp_category_posts.entry_id
INNER JOIN exp_categories ON exp_category_posts.cat_id = exp_categories.cat_id
WHERE t.entry_id !=''
  AND t.site_id IN ('1')
  AND t.entry_date < 1610109517
  AND (t.expiration_date = 0 OR t.expiration_date > 1610109517)
  AND t.entry_id  IN ('0','649','650','651','652','653','654','655')
;

if there are few values output is following, which is ok optimization ok

but if IN ('0','649','650','651','652','653','654','655', thousand values)查询运行约 1 分钟并解释对此的更改

failed

如何解决这个问题?

UPDATE: range_optimizer_max_mem_size had already set to 0 and isn't issue enter image description here


当有人运行一个包含很长的值列表的查询时,我们在我的公司遇到了类似的问题。IN (...)谓词。

我们发现 MySQL 对范围优化器可用的内存强制实施限制。如果值列表太长,则超出了内存限制,优化器无法完成其分析以查看是否应该使用索引。所以它放弃了,并说:“算了!这只是为你做的表扫描。”

我们通过设置 MySQL Server 配置值来修复它range_optimizer_max_mem_size=0这意味着范围优化器可以使用的内存没有限制。

这会产生一个风险,如果有人要运行一个包含一百万个值的查询IN (...)列表中,它可能会使用大量内存,也许足以杀死 MySQL 服务器。但到目前为止,这种权衡是更好的,允许优化器选择索引。

请参阅文档:

  • https://dev.mysql.com/doc/refman/5.7/en/range-optimization.html
  • https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_range_optimizer_max_mem_size

回复您的评论:

优化器选择执行表扫描的另一个常见原因是,它计算出您的条件与表的足够大的部分相匹配,因此使用索引比简单地运行表扫描并检查每一行的成本更高。

此阈值没有记录,它取决于基于成本的优化器的实现,因此它可能会因版本而异。但我的观察是,通常如果您的条件与表的 20% 以上匹配,优化器就会选择表扫描。

你可以使用索引提示告诉优化器将表扫描视为无限昂贵,因此索引优于表扫描。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我的查询在“IN”子句中有大量值时,MySQL 不使用我期望的索引 的相关文章

随机推荐

  • 在输出中打印 Python 版本

    如何从脚本中打印当前 Python 安装的版本号 Try import sys print sys version 这将打印完整的版本信息字符串 如果你只想要 python 版本号 那么巴斯蒂安 莱昂纳德的解决方案是最好的 您可能想要检查整
  • 正确安装 Android SDK、ADT 和 Eclipse 3.6.1

    按照 Eclipse 3 6 1 Classic 和 Android SDK 发布的说明 ADT 其中 OS 2 3 是最新的 错过了几个步骤 在 Eclipse 中加载 ADT 之前 一切似乎都正常 在此之前 将以下依赖项站点添加到列表中
  • 如何在 Metro/WinRT 中将主机名解析为 IP 地址?

    我正在将 WP7 应用程序移植到 Windows 8 Metro 我遇到的 许多 转换障碍之一是根据主机名或 DNS 名称发现 IP 地址 以下是我之前在WP7中使用的示例 DnsEndPoint dnsEnd new DnsEndPoin
  • xcode sqlite3 libsqlite.dylib

    我的项目出现了错误 但我不知道问题出在哪里 这是我编译后的错误 ld警告 在 install Platforms iPhoneSimulator platform Developer SDKs iPhoneSimulator3 0 sdk
  • 为什么我的 requirejs 配置中的 shim 的 `unit` 没有被调用?

    Update 我正在编写一个小模块来处理这个 csrf 令牌问题backbone直到我收到 Louis 答案的推送通知 他的回答很优雅 看起来不错 但我会离开a link to my 主干 csrfmodule github repo 仅供
  • Homebrew:安装新公式 php72-imagick

    我需要在我的 php 7 2 上安装 imagick 模块 I see brew search php72 gt Searching local taps gt Searching taps on GitHub gt Searching b
  • 我们可以在类中声明密封方法吗

    class X sealed protected virtual void F Console WriteLine X F sealed void F1 protected virtual void F2 Console WriteLine
  • 使用 C++ 将托管事件公开给 COM

    可以公开用 C 编写的托管事件 以便在使用 C 编写的 COM 对象中公开和使用 对 com 和 atl 不太熟悉 您能否展示一下 MSDN 文章中所示示例的 C 方面是什么样子的 http msdn microsoft com en us
  • 使用 ADO 处理 MS Access 中附件类型的字段

    我的数据库中有一些字段需要存储图像 位图 JPG 或 PNG 和 PDF 或 Excel RTF TXT 文件 通过互联网浏览 我了解到MS Access 2007 和更新版本 有一个类型字段Attachment这可以满足我的需要 但是 我
  • 如何获得算术中忘记转换的警告?

    考虑这种情况 uint64 t add uint32 t a uint32 t b return a b programmer neglected uint64 t a b 我们如何让 GCC 或任何其他编译器 的 C 或 C 前端对这种情
  • 使用 iOS/Obj-c 按流派搜索 Apple App store

    您将如何使用 Obj c 搜索 Apple App store 来执行以下操作 返回游戏总体类别中前 100 名的详细信息或 特定游戏类别 返回游戏类别中特定游戏的详细信息 Anyone 嗯 据我所知 您有两种方法来搜索 App Store
  • WPF 中图像填充按钮上的空间

    I have Button在我的 WPF 应用程序上 我想要一个Image来填补Button完全地 目前我有以下代码 它没有填充Button
  • 在 Unix 中根据模式重命名多个文件

    一个目录下有多个以 prefix 开头的文件fgh 例如 fghfilea fghfileb fghfilec 我想将它们全部重命名为以前缀开头jkl 是否有一个命令可以做到这一点 而不是单独重命名每个文件 有多种方法 但使用rename可
  • $().each 与 $.each 与 jQuery 中的 for 循环?

    我不明白为什么会发生这种情况 I read here那 首先 each构成一个single函数调用来启动 迭代器 第二 foo vals each makes three函数调用来启动 迭代器 第一个是 它生成一个新的 jQuery 包装器
  • 使用SQL Server CE;仅当不存在时才可以插入吗?

    我正在尝试验证一个简单的 1 字段表 以确定在插入重复项之前是否存在记录 if not exists select from url where url insert into url 有人可以帮忙吗 您的代码示例将在完整版本的 SQL 中
  • Rails 5.1.2 引导程序图标未在生产中提供

    这是一个很棒的地方 我希望尽快有能力贡献解决方案 拜托 有人帮忙吗 我看了几个小时的 YouTube 并阅读了网络上有关资产管道预编译的每一篇文章 无论出于何种原因 我决定使用 Rails 5 1 2 但我不知道这是否是问题所在 字形图标不
  • “分配”是 @property 编译器指令的默认设置吗?

    如果我定义一个属性并执行以下操作 property nonatomic UIButton button 那么我认为这是一个 分配 属性 那是对的吗 属性参数的默认值为 分配 读写和 原子 没有关键字 原子 只有非原子
  • Session.getActiveUser().getEmail() 不返回任何值

    这是我的第一个 Stackoverflow 问题 所以我尽力在这里做到清晰和结构化 但请原谅我的初学者错误 所以我对 Google 的脚本编辑器有一个小问题 基本上我是在调用Session getActiveUser getEmail 以及
  • 尝试在 PHP 中使用 $_FILE 时出现“未定义索引”错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 我可以轻松地将文件上传到数据库中 但是当我想编辑文件时
  • 当我的查询在“IN”子句中有大量值时,MySQL 不使用我期望的索引

    我遇到问题时IN子句包含太多值 考虑这个查询 EXPLAIN SELECT DISTINCT t entry id t sticky wd field id 104 t title FROM exp channel titles AS t