个人使用9: in有没有用到索引?

场景:老大来找我了。你对应sql写in来进行匹配,我在我电脑执行了下,速度很堪忧,小老弟你换另一种看看,本地用到了索引。
在这里插入图片描述
是一个简简单单的删除语句。用A表的主键去查询A-子表的明细,对应明细id 是B表的主键。然后一波带走删除。 我寻思我思路是ojbk的。对应 A-子表跟B表都可能是数据量很大的大表。这样删除会不会效率很慢?

想归想,闹归闹。总要拿出点证据。所以就去进行sql语句分析。
1.第一步 先在我电脑上直接执行
在这里插入图片描述
我的语句大概在0.44s

在这里插入图片描述
老大的语句大概在0.53 不过多跑几次 浮动范围是在0.41-0.55波动,上面就稳定很多了。

接下去进行 explain 进行sql运行语句分析。
在这里插入图片描述
图片是截图的,可能带模糊 大致我们关注 type 是ref 对应possible_keys 也有对应数据。
在这里插入图片描述
第二句也照样可。
二者的解析结果一致。所以下面语句应该没有特别快。或者是对应数据库本身一些进行过优化吗?
所以我再思考是否是数据库不同。
最后追溯过去是这样的。本地mysql数据库版本是8.0.x,老大的是仿线上数据库,对应版本是5.7.9 大版本是5.7 小版本只有9.对应运行结果也的确是下面sql执行用到索引了,对应上面的未使用到索引。
这里也额外百度查询了,对应5.7.17版本是查询问题时候,对应博主的版本号,也说in可以使用到索引。 那么暂时是5.7.17以下存在in无法匹配索引的问题,对应8是一定可以使用到in索引的。

额外补充:
对应来源一个比较好的博客分析 https://www.cnblogs.com/bulushengse/p/12703789.html
1.sql解析简单观察
在这里插入图片描述

我们只需要注意一个最重要的type 的信息很明显的提现是否用到索引:

type结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge >
unique_subquery > index_subquery > range > index > ALL

all:全表扫描

index:另一种形式的全表扫描,只不过他的扫描方式是按照索引的顺序

range:有范围的索引扫描,相对于index的全表扫描,他有范围限制,因此要优于index

ref:
查找条件列使用了索引而且不为主键和unique。其实,意思就是虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描。但它的好处是它并不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内扫描。

const:通常情况下,如果将一个主键放置到where后面作为条件查询,mysql优化器就能把这次查询优化转化为一个常量。至于如何转化以及何时转化,这个取决于优化器

一般来说,得保证查询至少达到range级别,最好能达到ref,type出现index和all时,表示走的是全表扫描没有走索引,效率低下,这时需要对sql进行调优。

当extra出现Using filesor或Using temproary时,表示无法使用索引,必须尽快做优化。

possible_keys:sql所用到的索引

key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL

rows: 显示MySQL认为它执行查询时必须检查的行数。

在这里插入图片描述

对应in 如果取值范围扩大,效率会变慢,大到一定程度。会不走索引,走全表扫描

  1. using 是什么?
    using()用于两张表的join查询,要求using()指定的列在两个表中均存在,并使用之用于join的条件。
    举例:
select * from 表1 inner join 表2 on 表1.相同的列=2.相同的列;
select 表1的列 from 表1 inner join 表2 on 表1.相同的列=2 .相同的列
等同于 select * from 表1 inner join 表2 using(相同的列);

对应比较好的参考using用到网址: https://blog.csdn.net/qq_38712932/article/details/82558805

最后采用了老大的代码。因为一个是二者都能匹配到索引,并且他那种在低版本也适用。另外就是in 数据越多可能会失效,所以感觉不是很好。


漫漫长路,一个小周跟他一个小陈朋友一起努力奔跑。


<think>嗯,用户问的是Python中哪些功能最少被使用。首先,我需要回忆Python的各种特性和功能,然后想想哪些是开发者通常不太常用或者容易被忽视的。比如,像`__import__`这样的内置函数,平时大家可能更倾向于使用import语句,而不会直接调用这个函数。还有`else`子句在循环和异常处理中的用法,可能很多人没怎么用过或者不知道。 接下来是`frozenset`,不可变的集合类型。虽然在某些需要哈希集合的情况下有用,但日常开发中可能大家更常用普通的set或者列表、字典之类的结构。还有`property`装饰器,虽然知道的人可能多,但实际项目中可能用得不够,或者没有充分利用其高级功能。 再考虑像`exec`和`eval`这样的动态执行函数,由于安全性和可维护性的问题,很多项目规范会禁止使用,所以这些功能可能用得少。还有`slice`对象,可能在自定义索引或切片操作时有用,但一般开发者可能直接使用切片语法,而不会显式创建slice对象。 还有`enumerate`的反向使用,比如获取索引和元素,但有时可能被忽略。还有`collections`模块中的一些数据结构,比如`namedtuple`或`deque`,虽然有用但可能部分开发者不了解或者不常用。 需要确定这些功能确实使用较少,可能结合社区讨论、常见代码库的分析,以及个人经验。例如,`else`在循环中的用法可能很多教程里没强调,导致开发者不知道。而`frozenset`在需要作为字典键的时候才会用到,这种情况相对少见。 然后,还要考虑是否有其他更冷门的功能,比如`contextlib`中的某些工具,或者`inspect`模块的功能,但可能这些属于标准库的范畴,而问题可能更侧重于语言核心功能。因此,重点放在语言本身的特性,而非库。 最后,整理这些点,给出每个功能的原因和示例代码,同时确保回答准确。可能还需要验证每个功能的实际使用频率,比如查看Stack Overflow的问题数量,或者GitHub代码中的出现频率,但作为思考过程,可能依赖已有的知识。 总结下来,用户可能需要了解Python中那些存在但不常被使用的特性,以及它们的适用场景。回答时需要简明扼要地列出这些功能,并解释为什么它们使用较少,同时给出示例。最后,相关问题需要围绕这些功能展开,帮助用户进一步了解每个特性的细节和应用场景。</think><< 在Python中,以下功能因其特定使用场景或替代方案的普及性,通常较少被主动使用: 1. **`__import__()` 函数** ```python # 常规导入方式 import os # 使用 __import__ 动态导入(较少使用) dynamic_os = __import__(&#39;os&#39;) ``` **原因**:开发者更倾向于使用`import`语句或`importlib`模块进行模块导入,直接调用`__import__()`会降低代码可读性。 2. **循环/异常中的`else`子句** ```python for i in range(5): if i == 3: break else: print("循环未被break中断") # 极少触发此分支 ``` **原因**:开发者容易忽略`else`在循环和`try`块后的逻辑,多数场景用`if`条件替代。 3. **`frozenset`(不可变集合)** ```python fs = frozenset([1, 2, 3]) # 无法修改: fs.add(4) 会报错 ``` **原因**:普通集合`set`能满足大部分需求,`frozenset`仅在需要哈希性(如字典键)时才会使用。 4. **`property`的完整描述符协议** ```python class Demo: @property def x(self): return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x ``` **原因**:多数开发者仅使用`@property`的getter功能,而忽略setter/deleter的完整实现。 5. **`exec`和`eval`的动态代码执行** ```python code = "print(&#39;Hello from eval&#39;)" eval(code) # 可能引发安全问题 ``` **原因**:动态执行代码存在安全隐患,且难以调试,通常被代码规范禁止。 6. **`slice`对象的显式使用** ```python s = slice(1, 5, 2) lst = [0,1,2,3,4,5] print(lst[s]) # 输出 [1,3] ``` **原因**:开发者更习惯直接写`lst[1:5:2]`,而非显式构造`slice`对象。 7. **`enumerate`的`start`参数** ```python for idx, item in enumerate([&#39;a&#39;, &#39;b&#39;], start=100): print(idx, item) # 输出 100 a, 101 b ``` **原因**:多数情况下索引从0开始即可满足需求,自定义起始值的使用场景较少。 8. **`memoryview`对象** ```python data = bytearray(b&#39;abcdef&#39;) mv = memoryview(data) print(mv[1:3].tobytes()) # 输出 b&#39;bc&#39; ``` **原因**:主要用于处理二进制数据的零拷贝操作,普通应用开发中极少涉及。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值