听闻有许多人是禁止开发人员在SQL中使用SELECT *的,这里翻译一下StackOverflow的一篇提问,个人认为相当客观

【SELECT *】危害主要有以下几点:

  • 给数据消费者传数据的低效。当你SELECT *后常常你会从数据库查询出比你应用的功能实际需要过多的列,这还可能导致多余数据从数据到服务端到客户端,从而导致机器负担的增加,同样地网络传输也会增加负担。特别当数据表增加了新列,但是功能实现那根本又不需要。
  • 索引问题。想象一下这样一个场景:你需要调一个Query调到一定的高性能。如果你用了SELECT *然后返回全部列超过了你需要的列,服务端经常需要为接收你的数据而消耗代价更多的函数而本来是不用的。举个例子,你不可能简简单单创建一个覆盖你SELECT出来全部列的索引,即使你这样做了(包含全部列,想想都可怕),下一个挖坑人又在数据表中增加了新的列就导致你原本已覆盖的索引无法优化了,然后你会惊奇地发现你的Query性能噗噗噗地下降,又没有明显的原因。
  • 绑定问题。当你SELECT *之后,有可能查询到来自两张表但是名称一样的列。这样可能会引起数据绑定端或者功能点崩溃,想想返回来有两列数据都是ID,谁TM知道用哪一列?SELECT *还可能搅乱视图(部分数据库、版本)——当底层数据表结构改变,视图又没有新建,视图的数据可能会返回无意义的数据(名称乱不好维护?)。最惨的,你能折腾好以你命名的列,但新来的挖坑人要加入列的时候就不知道他应该如何命名列名才不会与你已经埋好的列名冲突了。

但并不是说【SELECT *】只有坏处,以下用例就可以宽泛地使用:

  • 临时查询。当调试东西,特别是某一表自己不熟悉的时,SELECT *就显得很友好了。自己就不用先研究一番这表有啥表明了。这样表的列名越长SELECT *加分就越高。
  • 当*表示一行。在下面的用例中SELECT *没啥问题的——之前也有谣传这样写是性能杀手,也许这传说几年前还有点说服力,但是现在不是:
    SELECT COUNT(*) FROM table;

    在此用例中“*”表示“数一下行数”,如果你用列名替代这表示要数一下列对应值不为NULL的行数。对我来说,COUNT(*)才是本质意义的数行数,这样你也避开了擦边案例(例如聚合搜索中应被消除的NULL值)【译者觉得还是COUNT(Id)或者COUNT(主键)靠谱,这里只是说明数行数的情况,即SELECT * 代表一行时使用没啥毛病】
    以下类型的Query也是一样的:

    SELECT a.ID FROM TableA a
    WHERE EXISTS (
    SELECT *
    FROM TableB b
    WHERE b.ID = a.B_ID);

    在任何合格的数据库中,“*”就是表示“一行”,不管你在子查询中放了啥。一些人用在SELECT中用ID或者数字1,在我看来在这些约定相当的扯淡。你的意思是要“数行数”,“*”就是用来干这个的。做这些查询优化的知道这个的都是智者。(实际上,我只知道SQL Server和Oracle就是这样的)

关于SQL中SELECT *(星号)的危害论的更多相关文章

  1. SQL中SELECT INTO和INSERT INTO SELECT语句介绍

    表复制是经常要用到的操作,下面就将为您介绍SQL中SELECT INTO和INSERT INTO SELECT语句,供您参考. Insert是T-sql中常用语句,Insert INTO table( ...

  2. PL/SQL中SELECT总结

      一.SELECT 语句的各个关键词的顺序及作用简解(这个我简略点写~) 1.SELECT 2.FROM 3.WHERE 4.GROUP BY ---对结果集进行分组,通常与聚合函数一起使用 5.H ...

  3. SQL 中 SELECT 语句的执行顺序

    好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 " ...

  4. 在sql中select的执行顺序

    <select{[distinct |all] columns |*}> [into table_name] <from {tables |views | other select} ...

  5. 【SQL】SQL 中Select语句完整的执行顺序

    SQL Select语句完整的执行顺序: 1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函 ...

  6. sql中select into和insert into的区别

    select into主要是作用于没有新建表,在复制数据的时候新建 insert into主要作用于已经新建了一个表,直接把要复制的数据复制到新建好的表中

  7. \G,sql中select 如果太长,可以在后面放\G,竖行显示~~~~

    1.使用\G按行垂直显示结果 如果一行很长,需要这行显示的话,看起结果来就非常的难受. 在SQL语句或者命令后使用\G而不是分号结尾,可以将每一行的值垂直输出. mysql> select * ...

  8. SQL中select与set的区别-转载

    下表列出 SET 与 SELECT 的区别   SELECT SET 同时对多个变量同时赋值时 支持 不支持 表达式返回多个值时 将返回的最后一个值赋给变量 出错 表达式未返回值时 变量保持原值 变量 ...

  9. sql中select语句的逻辑执行顺序

    下面是SELECT语句的逻辑执行顺序: FROMONJOINWHEREGROUP BYWITH CUBE or WITH ROLLUPHAVINGSELECTDISTINCTORDER BYTOP M ...

随机推荐

  1. putty WinScp 免密登录远程 Linux

    该方法的原理是预先生成一对公钥和私钥,私钥以文件的形式保存在本地,公钥保存在远程机器上.这样每次登录只需指定私钥文件,远程机器通过比对公钥和私钥来验证登录的合法性. Putty 免密登录 第一步 生成 ...

  2. 在spring boot里使用undertow而非tomcat

    参考https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-o ...

  3. Excel 截取字符,判断县区 城市。

    https://jingyan.baidu.com/article/624e7459aa90e434e8ba5a8a.html https://jingyan.baidu.com/article/9f ...

  4. 避免git clone和push时每次都需要输入用户名和密码

    有三种方式解决git clone时每次都需要输入用户名和密码, 1. SSH免密方式 使用git bash ssh-keygen或puttygen.exe生成公钥. 2. 配置全局开机存储认证信息 下 ...

  5. Promise和Observable的映射

    前言 promise解决了嵌套地狱的问题,Observable解决了promise只有一个结果,和不可以取消的问题. 使用的是rxjs6版本. 这篇文章是方便使用Observable的API替换Pro ...

  6. promise 和 async await比较

    async搭配await是ES7提出的,它的实现是基于Promise.这里使用它对比Promise的用法,这里只是简单的适合日常业务的使用场景.   async.await是ES7中的提案,通过同步方 ...

  7. Manytasking optimization MATP

    Manytasking Jmetal代码反向解析1_MATP测试函数集 觉得有用的话,欢迎一起讨论相互学习~Follow Me 这是我在写Manytask optimization时的笔记,代码地址可 ...

  8. ODAC Developer Downloads - Oracle Universal Installer

    https://www.baidu.com/link?url=BL2vRNMWap6AFJcmsFCEKi3KxZ2SgmtVJoihVKhF-SPgzvJHNkbk_j7nz1HdtAAWZ22NM ...

  9. Angular2 输入完成后触发函数

    (blur)="keySearch($event)" ,鼠标点击其他地方触发 keySearch(e): void { var dom = $(e.target); var key ...

  10. 【Spring Boot学习之七】自定义参数&多环境配置&修改端口号&yml

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.自定义参数通过注解直接获取配置文件application.properties中配置key的value1.appl ...