ARTS Week 31


Algorithm

本周的 LeetCode 题目为 SELECT * 有多慢

最广为人知的查询优化规则就是尽可能避免使用SELECT *,即使需要用到所有列,那么也应该全部列出它们的名称。表面看起来SELECT *会读取不必要的列,但更深层次的原因是:

  • 这些列是从内存或磁盘中读取的,读取不必要的列会带来更高的资源使用率和更高的延迟
  • 如果是从磁盘中读取,它可能会被缓存,那么将会浪费不必要的内存
  • 列也有可能通过网络发送,将会给服务器和网络带来更多开销

在某些情况下SELECT *将会严重影响整体应用程序性能:

  1. 列式数据库,很多数据库都是列式数据库,将不同的列存储到不同的数据结构中,如此使得SUM(column)更快,而SELECT *却会比较慢。
  2. 覆盖查询。对比 SELECT id, surname FROM user WHERE surname < 'c';SELECT * FROM user WHERE surname < 'c';,如果在id上存在索引,那么前者可以通过索引来快速读取到行中对应内容进行比较,而后者却不行:
  3. 列的数量,当一个表中列太多时,仅通过id依旧无法读取到所有列中数据
  4. 生成列/虚拟列。SQL语句执行时会计算生成虚拟列,有些情况下会写入磁盘进行保存,有些情况下会即使计算,当即使计算时,那么将会带来更大的开销
  5. 视图。视图建立在JOIN操作上,只选择需要的列可能会忽略一些不必要的表,从而使查询速度更快
  6. InnoDB 文本和 BLOB。在 InnoDB(MariaDB 和 MySQL 默认存储引擎)中,大的可变长度文本和二进制列存储在单独的内存页中。当长数据存储在单独的页面中,读取它至少需要一次物理读取。这会影响性能。

最后,SELECT * 不是一个好的做法,但它对查询性能和服务器资源使用的影响通常被夸大了。通常其他方面更为重要,即使用索引和避免使用内部临时表进行两步排序。

Tip

最近刚开始接触 Shell 脚本,Shell 脚本中的多行注释写法:

: '
This is a
comment
in shell script
'

Share

本周是隔离的第二周,预计接下来的几周还会继续被隔离,目前已基本适应了这样的生活。打算先休息停更一段时间,好好地整理、思考一下,望周知。