听闻有许多人是禁止开发人员在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. shell for循环输出目录下的文件名

    test.sh文件: #!/bin/bash for file in `ls`;do echo $file done 输出 bogon:test macname$ chmod +x test.sh b ...

  2. js限制输入数字能输入小数点,js定义数组,js往数组中添加数据,js将字符型转为数字型,除法结果保留两位小数——js小测:计算比赛得分

    一个朋友跟我说要去给某个比赛算分: 规则:去掉最低分最高分求平均分: 最近在学习大数据可视化——图谱,用到js一些东西,所以今天就用js练练 用到知识点: js限制输入数字能输入小数点,js定义数组, ...

  3. minimap2 长reads比对工具

    minimap2 github 官网 https://github.com/lh3/minimap2 安装 git clone https://github.com/lh3/minimap2 cd m ...

  4. [技术博客]windows中使用docker技术

    背景 我们的工程使用了一个叫做termux的安卓上的linux终端,这个终端在所有的软件包里硬编码了软件的运行路径(/data/data/com.termux/..),由于安卓系统的权限设计,我们名为 ...

  5. windows 10环境下安装Tensorflow-gpu

    网上有很多教程,特别是简写上的写的都还算比较详细.但我自己还是遇到了几个坑,希望对深度学习有兴趣的同学遇到跟我一样的坑,希望这份记录能帮助到你. 问题一:要不要使用Anaconda? 我看极客时间上的 ...

  6. Executors创建四种线程池

    newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixedThreadPool 创建一个定长线程池,可控制线程 ...

  7. 僵尸进程bug排除方法

    多进程处理存在的问题 直接return 200 子进程 signal.signal(signal.SIGCHLD, signal.SIG_IGN) #不管子进程,不然R的多进程切图会产生僵尸进程

  8. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案-Onvif(一)使用Onvif协议进行设备发现以及指定设备信息探测

    背景分析 众所周知,EasyNVR不拘泥.不受限于摄像机的品牌厂商及其配套平台,只要是网络监控摄像机IPC.硬盘录像机NVR.且设备支持标准的RTSP/Onvif协议,都可以接入实时视频流进入Easy ...

  9. LwIP应用开发笔记之六:LwIP无操作系统TCP客户端

    上一篇我们基于LwIP协议栈的RAW API实现了一个TCP服务器的简单应用,接下来一节我们来实现一个TCP客户端的简单应用. 1.TCP简述 TCP(Transmission Control Pro ...

  10. VisualVM使用

    sualVM是JDK自带的一个用于Java程序性能分析的工具 在JDK安装目录的bin文件夹下名称为 jvisualvm.exe 在左侧选择应用 (1)概述 应用程序和运行时环境的基本信息 基本参数 ...