描述

大家通常禁止在生产环境直接使用select * 已成常识了,也常常在开发规范中就会规定不允许直接使用select *,那么我们为什么不允许使用select * ,在一些什么场景下select * 会出问题?能否控制不能直接使用select *?出于这些疑问,我们特别测试记录一下。

 

测试环境

Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 
Feb 10 2012 19:39:15 
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: )
 

select * 可能会造成业务功能出错

假设我们有一个视图 V_test 代码如下:
 CREATE VIEW v_test
AS
SELECT *
FROM test
你在web前端调用直接使用如下脚本并对应好显示的字段,当时功能是正常的。
   SELECT  *
FROM v_test
test 表结构如下:

后来因为业务调整,有人调整了test表 ,并加一个字段F ,那么接下来的后果就会前端相应的功能因新增的字段F直接报错。

 

select * 可能会造成性能方面的问题

测试数据准备
 --新建测试表
IF OBJECT_ID('test', 'U') IS NOT NULL
DROP TABLE test;
CREATE TABLE test
(
id int IDENTITY(1, 1) ,
a nvarchar(20) ,
b nvarchar(15) ,
c nvarchar(20) ,
d int ,
e float
);
 --造测试数据
DECLARE @i INT;
SET @i = 10000;
WHILE ( @i > 0 )
BEGIN
INSERT INTO test
( a ,
b ,
c ,
d ,
e
)
SELECT RAND() * 1000 ,
RAND() * 1000 ,
REPLICATE('a', 3) ,
@i ,
@i - 1;
SELECT @i = @i - 1;
END;
 --新建索引(主键、非聚集索引)
ALTER TABLE dbo.test ADD CONSTRAINT PK_test_id PRIMARY KEY(ID);
CREATE INDEX IX_test_1 ON dbo.test(a);
查询条件使用主键字段的执行计划,主键是默认覆盖全部字段。

如直接使用字段a做查询条件

还是聚集索引扫描,全表扫,无法使用我们已新建好的非聚集索引IX_test_1,在上述语句中因该索引未覆盖到非a 的字段。假设实际场景我们只需取a字段,那么执行计划又是怎么样的?

如上图,就会走我们期望的索引,同时也可以减少因select * 而多读的字段(id、b、c、d、e)的网络传输,所以,尽量指定自己所需的字段名,可以避免一些无谓的性能开销。

 

如何控制不让 select *

假设我们不允许在上述测试表test上执行select * 可以如何处理
 --新建测试表
IF OBJECT_ID('test', 'U') IS NOT NULL
DROP TABLE test;
CREATE TABLE test
(
id int IDENTITY(1, 1) ,
a nvarchar(20) ,
b nvarchar(15) ,
c nvarchar(20) ,
d int ,
e float,
abort_select_all AS (1/0) ---新增控制字段
);
--造测试数据
DECLARE @i INT;
SET @i = 10000;
WHILE ( @i > 0 )
BEGIN
INSERT INTO test
( a ,
b ,
c ,
d ,
e
)
SELECT RAND() * 1000 ,
RAND() * 1000 ,
REPLICATE('a', 3) ,
@i ,
@i - 1;
SELECT @i = @i - 1;
END;
--新建索引 (主键、非聚集索引)
ALTER TABLE dbo.test ADD CONSTRAINT PK_test_id PRIMARY KEY(ID);
CREATE INDEX IX_test_1 ON dbo.test(a);
如下图,如果select *  因读取了abort_select_all字段(1/0)就会直接报错,从而达到不能直接select *的效果;

直接按字段名查询没有问题(非abort_select_all字段)。

直接按字段名查询没有问题。

 

SELECT * 测试的更多相关文章

  1. Mybatis-Plus 实战完整学习笔记(七)------select测试二

    1.查询selectOne  (3.0.3版) @Test public void selectMethod() throws SQLException { // 根据ID获取一个对象的数据 Empl ...

  2. Mybatis-Plus 实战完整学习笔记(六)------select测试一

    查询方法(3.0.3) 1.查询一个员工的数据 @Test public void selectMethod() throws SQLException { // 根据ID获取一个对象的数据 Empl ...

  3. sysbench 压力测试

    200 ? "200px" : this.width)!important;} --> 介绍 sysbench是一个模块化.跨平台.多线程基准测试工具,主要用于测试不同系统参 ...

  4. (十二)select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型:int select(int maxfd,fd_set *rdset ...

  5. select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    http://hi.baidu.com/%B1%D5%C4%BF%B3%C9%B7%F0/blog/item/e7284ef16bcec3c70a46e05e.html select函数用于在非阻塞中 ...

  6. Hibernate框架的基本搭建(一个小的java project的测试向数据库中插入和查询数据的功能)

    Hibernate介绍:Hibernate是一种“对象-关系型数据映射组件”,它使用映射文件将对象(object)与关系型数据(Relational)相关联,在Hibernate中映射文件通常以&qu ...

  7. select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)

    select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型, 原型: int select(int maxfd,fd_set *rds ...

  8. sysbench 0.5 oltp测试笔记

    sysbench 0.5相比0.4版本的主要变化是,oltp测试结合了lua脚本,不需要修改源码,通过自定义lua脚本就可以实现不同业务类型的测试.同时0.5相比0.4需要消耗更多的cpu资源. 1. ...

  9. select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET (转)

    select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型: #include <sys/time.h>       ...

随机推荐

  1. angular打印功能实现方式

    目前主流的前端打印方式有两种:一种是使用浏览器打印功能直接打印页面,另一种是调用本地控件实现.浏览器打印功能单一,不适用于复杂的业务表单,而打印控件可以设计打印模板,实现复杂表单的打印,十分适合复杂的 ...

  2. OJ问题集合

    1.找出给定数组之中的3个和为0的数. 2.给出一个字符串,给出需要去除的字符串,返回去除需要去除的字符串后的值. 3.一个数组之中的第二最大值三个数的组合.

  3. thinkphp方法success和error跳转时间以及返回ajax

    Action类的success和error方法第三个参数为数字时候,表示指定页面跳转时间,例如: $,); $,); 如果是ajax跳转 必须用true: $this->success('操作成 ...

  4. C++——INI文件详解

    原创声明:本文系博主原创文章,转载及引用请注明出处. 1. INI文件介绍 INI是英文单词 INItialization 的缩写,常作为Windows系统下的配置文件.INI文件是文本文件,通常用于 ...

  5. 使用python获得屏幕截图并保存为位图文件

    直接上代码: import win32gui import win32ui from ctypes import windll import Image hwnd = win32gui.FindWin ...

  6. Redis主从复制配置+哨兵模式

    架构设计: master:s0 slave:s1.s2 主机映射信息如下: 192.168.32.100 s0 192.168.32.101 s1 192.168.32.102 s2 1.安装Redi ...

  7. Quartus 18 新手使用教程

    最近需要做个小作品,用到了Quartus 18,本人采用vhdl语言进行的开发,过程如下. 1.点击新建一个工程 ​ 2.选择工程保存的路径,填写工程名称 ​ 3.选择工程类型为空的工程 ​ 4.不添 ...

  8. K8S中DaemonSet

    DaemonSet DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本.当有 Node 加入集群时,也会为他们新增一个 Pod .当有 Node 从集群移除时,这些 Pod ...

  9. zookeeper系列(四)zookeeper的使用场景

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败. 出处:http://www.cnblogs.com/leesf456/p/6036548.html感谢原著公开这么好的博文供大家学习 ...

  10. 搞清楚MySQL事务隔离级别

    首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 然后往表中插入两条数据,插入后结果如下: 为了说明问题 ...