为啥阿里巴巴禁用select *

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥阿里巴巴禁用select *相关的知识,希望对你有一定的参考价值。

参考技术A

阿里巴巴开发手册中指出:
【强制】在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明
说明:

首先介绍一下mysql基本架构,基本结构如下图:

MySQL 基本架构可以分为 Server 层和存储引擎层两部分。Server 层包括连接器、查询缓存、分析器、优化器、执行器等。存储引擎层负责数据的存储和提取,其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎

当我们执行一条查询语句:select * from t where id = 1,在MySQL中执行过程如下:

假设有一条sql语句为select * from t where name = "何甜甜",其中id为主键,name为索引,而实际上这么写的目的只是想查询指定name的id
在innodb存储引擎中,索引可以分为非主键索引和主键索引,主键索引和主键的区别在于叶子节点存放数据的不同。主键索引中叶子节点存放的是整行数据,而非主键索引中叶子节点存放的是主键的值。现在我们来看select * from t where name = "何甜甜"这条语句是如何执行的
因为name是索引且name是查询条件,查询优化器会选择使用name索引。首先根据name查询到该name对应的主键id为1,因为需要查询的是指定name的所有数据,因此还需要根据主键id进行一次 回表 操作。所谓回表操作是指非主键索引中查询到主键id,在根据主键id到主键索引中查询到所有数据,具体过程可看下图

前面已经提到查询到的 中只是用到了id字段,如果将原来的sql语句修改为select id from t where name = "何甜甜",就可以避免一次回表操作。在非主键索引中已经覆盖了查询需求【即所需查询的ID已在非主键索引上了】,也被称为 覆盖索引 *。通过覆盖索引可以减少回表次数,从而显著提升查询性能,因此在实际写sql过程中应该尽量避免写select * 这样的查询语句,写之前先反问是否真的需要用到这么多字段

BLOB和TEXT是为了存储很大的数据而设计的字符串数据类型,当BLOB和TEXT值太大时,InnoDB会使用专门的外部存储区域来进行存储,每个值在行内需要1~4字节存储一个指针,然后在外部存储区域存储实际的值,如果查询的*中有BLOB或TEXT类型的字段,则查询的BLOB或TEXT列需要在进行额外一次IO操作去外部存储区域将数据查询到,所以尽量避免使用select *

传输数据过多会增加网络开销。同时,查询语句执行时会先将查询到的数据放到查询缓存区中,再从查询缓存中将结果返回给客户端,如果查询到的数据量非常大则需要花很多时间来存储结果,所以在说一次,避免使用select *

在实际开发中应尽量避免写select *这样的SQL语句,虽然通常情况下即使真的写了这样的select *这样的SQL语句,对项目的影响可能也没这么大,但好习惯还是要养成的
我还是觉得之前写的文章也很不错, 用户管理模块:如何保证用户数据安全 ,还是要再继续宣传一波,点个赞在走吧

为啥 SELECT 在 SQL Server 中创建未提交的事务?

【中文标题】为啥 SELECT 在 SQL Server 中创建未提交的事务?【英文标题】:Why is SELECT creating an uncommitted transaction in SQL Server?为什么 SELECT 在 SQL Server 中创建未提交的事务? 【发布时间】:2018-09-19 04:09:36 【问题描述】:

我在 SSMS 中禁用了自动提交。 我今天一直在玩它,经过一些奇怪的(无论如何对我而言)行为将用例缩小到以下范围:

连接到数据库 打开一个新的查询(ctrl n)

发出一个简单的 SELECT 语句,例如

从 AdventureWorks2017.Person.Person 中选择 TOP (5) *

关闭窗口

我在对话框(对话,嗯)框中收到以下消息:

There are uncommitted transactions. Do you wish to commit these transactions before closing the window?

作为 Oracle 的老用户,我知道 Oracle 和 SS 在锁定方面存在差异,但selects 导致需要提交或回滚的未完成事务?真的吗?这不可能,当然。没有数据发生变化。请问有人能解释一下吗?提前致谢。

【问题讨论】:

【参考方案1】:

当您使用控制台时,它会自动将您的查询放入事务中。因为您还没有关闭在您开始运行任何类型的查询时它自动启动的事务,所以您仍然有一个事务处于打开状态。

这篇 MSDN 文章对此进行了一些讨论。 https://docs.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql

【讨论】:

有点。过去跟踪所有这些的一个好方法是打开 SQL 分析器并观察所有事件并查看幕后发生的事情。 您可以在选择之前和之后执行 Print @@TRANCOUNT 并查看值是多少。根据文档,如果 trancount > 0 它不会创建另一个 Begin Trans...但是您在示例评论中的第一条语句会。 哦,没有看到你的第二个问题埋在那里。我记得,除非您明确打开第二个事务,否则您不会有两个事务。您通常每个窗口都有一个。我个人通常在 SSMS 中启用自动提交,因为在很多时候回滚事务相当容易,而且我更像是开发人员而不是 DBA。处理实时数据是为了像我现在这样的大胡子。 @JL_SO,你问的是不可能的,选择语句的自动提交和数据修改的 IMPLICT_TRANSACTIONS ON。请注意,与 Oracle 不同,SQL Server 允许在事务中进行 DDL,因此 CREATE 将启动 IMPLICT_TRANSACTIONS ON 的事务。 有多个并发级别。我相信 SNAPSHOT_ISOLATION 更接近您习惯使用 Oracle 的方式。

以上是关于为啥阿里巴巴禁用select *的主要内容,如果未能解决你的问题,请参考以下文章

为什么阿里巴巴要禁用Executors创建线程池?

为什么阿里巴巴要禁用 Executors 创建线程池?

为什么阿里巴巴要禁用 Executors 创建线程池?

阿里面试官鬼得很,问我为什么他们阿里要禁用Executors创建线程池?

为啥阿里巴巴吧矢量图库搜索不了了

为什么阿里要禁用 Executors 创建线程池?