开发者社区> 问答> 正文

MySQL不使用带有WHERE IN子句的索引??mysql

我正在尝试优化Rails应用程序中的一些数据库查询,但有几个让我感到困惑。它们都使用INin WHERE子句,并且都进行了全表扫描,即使适当的索引似乎已经到位。

例如:

SELECT user_metrics.* FROM user_metrics WHERE (user_metrics.user_id IN (N,N,N,N,N,N,N,N,N,N,N,N)) 执行全表扫描并EXPLAIN说:

select_type: simple type: all extra: using where possible_keys: index_user_metrics_on_user_id (which is an index on the user_id column) key: (none) key_length: (none) ref: (none) rows: 208 使用IN语句时是否不使用索引,或者我需要做不同的事情吗?这里的查询是由Rails生成的,因此我可以重新定义我的关系的定义,但是我认为我首先要从数据库级别的潜在修复开始。

展开
收起
保持可爱mmm 2020-05-17 10:04:56 600 0
1 条回答
写回答
取消 提交回答
  • 在向表中添加额外的2000左右行之后,还要验证MySQL是否仍执行全表扫描user_metrics。在小型表中,按索引访问实际上比表扫描更昂贵(在I / O方式上),MySQL的优化程序可能会考虑到这一点。

    与我之前的文章相反,事实证明MySQL也在使用基于成本的优化器,这是一个好消息-也就是说,ANALYZE如果您认为数据库中的数据量足以代表数据库运行了至少一次,将来的日常使用。

    在处理基于成本的优化器(Oracle,Postgres等)时,您需要确保ANALYZE在其大小增加10-15%以上时,定期在各种表上运行。(默认情况下,Postgres将自动为您执行此操作,而其他RDBMS将把此职责留给DBA(即您)。)通过统计分析,ANALYZE将有助于优化程序更好地了解I / O量(以及其他相关资源)在各种候选执行计划之间进行选择时,将涉及到诸如CPU之类的,例如用于排序的信息。运行失败ANALYZE可能会导致非常糟糕的规划决策,有时甚至是灾难性的决策(例如,由于s 上的嵌套循环不好,毫秒查询有时会花费数小时JOIN)。

    如果运行后性能仍然不能令人满意ANALYZE,则通常可以使用提示来解决该问题,例如FORCE INDEX,而在其他情况下,您可能会偶然发现MySQL错误(例如,这个较旧的错误可能会咬住您的本人)。使用Rails的nested_set)。

    现在,由于您使用的是Rails应用程序,因此ActiveRecord使用提示来发出自定义查询而不是继续使用ActiveRecord-生成的查询将很麻烦(并且破坏的目的)。

    我已经提到过,在我们的Rails应用程序中,所有 SELECT查询在切换到Postgres后都降至100ms以下,而ActiveRecord由于内部表扫描的嵌套循环,即使使用索引,由MySQL 生成的某些复杂联接有时也可能需要15s或更长时间。可用。没有哪个优化器是完美的,您应该注意这些选择。除了查询计划优化之外,还需要注意其他潜在的性能问题。但是,这超出了您的问题范围。来源:stack overflow

    2020-05-17 10:11:03
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
搭建电商项目架构连接MySQL 立即下载
搭建4层电商项目架构,实战连接MySQL 立即下载
PolarDB MySQL引擎重磅功能及产品能力盛大发布 立即下载

相关镜像