ARTS Week 31
Algorithm
本周的 LeetCode 题目为 SELECT *
有多慢
最广为人知的查询优化规则就是尽可能避免使用SELECT *
,即使需要用到所有列,那么也应该全部列出它们的名称。表面看起来SELECT *
会读取不必要的列,但更深层次的原因是:
- 这些列是从内存或磁盘中读取的,读取不必要的列会带来更高的资源使用率和更高的延迟
- 如果是从磁盘中读取,它可能会被缓存,那么将会浪费不必要的内存
- 列也有可能通过网络发送,将会给服务器和网络带来更多开销
在某些情况下SELECT *
将会严重影响整体应用程序性能:
- 列式数据库,很多数据库都是列式数据库,将不同的列存储到不同的数据结构中,如此使得
SUM(column)
更快,而SELECT *
却会比较慢。 - 覆盖查询。对比
SELECT id, surname FROM user WHERE surname < 'c';
和SELECT * FROM user WHERE surname < 'c';
,如果在id
上存在索引,那么前者可以通过索引来快速读取到行中对应内容进行比较,而后者却不行: - 列的数量,当一个表中列太多时,仅通过id依旧无法读取到所有列中数据
- 生成列/虚拟列。SQL语句执行时会计算生成虚拟列,有些情况下会写入磁盘进行保存,有些情况下会即使计算,当即使计算时,那么将会带来更大的开销
- 视图。视图建立在JOIN操作上,只选择需要的列可能会忽略一些不必要的表,从而使查询速度更快
- InnoDB 文本和 BLOB。在 InnoDB(MariaDB 和 MySQL 默认存储引擎)中,大的可变长度文本和二进制列存储在单独的内存页中。当长数据存储在单独的页面中,读取它至少需要一次物理读取。这会影响性能。
最后,SELECT *
不是一个好的做法,但它对查询性能和服务器资源使用的影响通常被夸大了。通常其他方面更为重要,即使用索引和避免使用内部临时表进行两步排序。
Tip
最近刚开始接触 Shell 脚本,Shell 脚本中的多行注释写法:
: '
This is a
comment
in shell script
'
Share
本周是隔离的第二周,预计接下来的几周还会继续被隔离,目前已基本适应了这样的生活。打算先休息停更一段时间,好好地整理、思考一下,望周知。