V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
sheaned
V2EX  ›  MySQL

sql 性能讨论

  •  
  •   sheaned · 1 天前 · 2207 次点击
    在 sql 查询中都说不推荐使用 select *,而是指定字段,性能会更好。尤其是返回大量数据的情况下。
    那么如果只返回一条数据的情况下,select * 和指定字段性能上会有多大的区别呢?
    24 条回复    2025-02-07 19:23:19 +08:00
    whrss9527
        1
    whrss9527  
       1 天前
    如果 select 索引字段,条件也在索引上,大表会走索引查询,无需回表就可以查到数据,这时候性能上会快很多。
    dylanqqt
        2
    dylanqqt  
       1 天前
    如果 select 字段没有命中索引,你 select 字段和你 select * 差不了多少。
    glacer
        3
    glacer  
       1 天前
    @dylanqqt 网络传输有区别
    coderzhangsan
        4
    coderzhangsan  
       1 天前
    以 mysql innodb 引擎为例,主键和唯一键查询,只返回一条数据,因为聚簇索引结构,所以 * 和 指定字段没啥区别。
    iyiluo
        5
    iyiluo  
       1 天前
    没发比,如果字段里面有 text 类型,网络传输都要一段时间,如果都是 int 类型的字段,一两条根本没什么区别。总之养成好习惯,只返回需要的
    ksedz
        6
    ksedz  
       1 天前
    性能差别不大,但是后续维护上 DDL 语句添加字段有可能让你之前的 select * 代码挂掉。
    spritecn
        7
    spritecn  
       1 天前
    @dylanqqt 对只要不是索引直出,都差不多,但有大字段或一直查千以上条的话就得考虑出口的 IO
    spritecn
        8
    spritecn  
       1 天前
    话说,被这个 select * 优化坑的年轻人不是一个两个啊
    Configuration
        9
    Configuration  
       1 天前
    0.0001 秒
    0.00001 秒

    有多大差距?可以说没多大差距,也可以说有 10 倍差距
    OliverDD
        10
    OliverDD  
       1 天前
    这句话有个前提,是列式数据库还是行式数据库。如果是行式数据库,没啥区别,对于硬盘层都是读取整行的数据后,在内存中过滤掉你不要的列;而如果是列式数据库,那就涉及到 IO 次数了,只选择你需要的行远比 select *快得多的多。
    dylanqqt
        11
    dylanqqt  
       1 天前
    @glacer 除非非常非常多的数据,不然的话区别可以忽略不计,并且 op 说了只返回一条数据,这基本没影响。
    LPJD
        12
    LPJD  
       1 天前
    看列的数量,返回结果内容的数量,被请求次数。管理系统,大部分情况优不优化 select*丝毫不影响用户体验
    foufoufm
        13
    foufoufm  
       1 天前
    感觉除了 slelect * 性能的问题,还有一点好处是可读性吧?
    linora
        14
    linora  
       1 天前
    对 oracle 深入了解一些的应该都有听过 sga 和 pga

    sga:全局缓存区
    pga:会话对应 server 端进程对应缓存区

    select 操作中有一步叫做字段投影,即将 sga 中数据块中相关行的相关的列放到 pga 中去

    所以仅 select 一部分列的操作相对 select *,pga 中占用内存会少一些
    lvlongxiang199
        15
    lvlongxiang199  
       1 天前
    为啥不自己构造数据试下呢
    yinmin
        16
    yinmin  
       1 天前 via iPhone   ❤️ 3
    select * 还有一个潜在的问题,如果存在多表 join ,随着项目多期开发,表字段会发生变更,如果某个表添加了另外一个表的同名字段,而 2 个表正好有 join ,这时 select *会出现歧异性。而且此类错误很容易在测试阶段没被发现,上线后造成事故。

    所以,很多公司有规定,select 不允许用*,字段必须加上表别名。
    jun771480011
        17
    jun771480011  
       1 天前
    不谈流量的话:一条数据没有区别;
    guanhui07
        18
    guanhui07  
       1 天前
    大字段就有 io ,通常区别不大,个人还是喜欢取该取的字段足够就好了 而不是 *
    coder01
        19
    coder01  
       1 天前
    @yinmin 这个坑我遇到过
    NoKey
        20
    NoKey  
       1 天前
    50 个字段,只查 1 个字段,也要*么?问题要结合实际场景来看。
    yinmin
        21
    yinmin  
       1 天前 via iPhone
    @coder01 #19 如果项目开工时没有严格要求:不需要用 select *,字段必须加表别名;掉坑里再返工工作量还是蛮大的。
    Richared
        22
    Richared  
       1 天前
    其实我还真没咋遇见过要写 select * ,简单查询都是插件生成的,有 basefield ,其他的好些你都得 as 别名,直接*返回 map ?写*记得 join 的时候给表起别名,要不冲突了。别的无所谓,想怎么干就怎么干,自己怎么舒服怎么来。
    JerryJet
        23
    JerryJet  
       1 天前
    两个方面:索引和数据大小。一条数据也可能包含很多字节
    stabc
        24
    stabc  
       1 天前   ❤️ 1
    大多数回答都驴唇不对马嘴
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2786 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:03 · PVG 22:03 · LAX 06:03 · JFK 09:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.