您当前的位置:首页 > 电脑百科 > 数据库 > 百科

SQL 中判断条件的先后顺序,会引起索引失效吗?

时间:2020-08-21 10:36:13  来源:  作者:
SQL 中判断条件的先后顺序,会引起索引失效吗?

 

在群里看到一个基础题,有关索引的使用。

SQL 中判断条件的先后顺序,会引起索引失效吗?

 

题目就在这里,有的朋友说选B,有的选C,有的说题目不严谨,还有的说没答案,都是错误的。

讨论了很久,有两个共性的问题,值得拿出来说下:

  • a=1 and b=1 和 b=1 and a=1 会有效利用 idx(b,a) 吗?
  • b=1 还会利用索引 idx(a,b)吗?

实践出真知,我就试着上机操作下。

create database factory ;

use factory 
go 

create table dbo.workflow ( flowid int, flowamount int, flowcount int )

go 

先回答第一个问题,判断条件的顺序会影响索引使用吗

这儿模拟题目中的 idx(b,a) 索引结构

create index idx_amt_id on dbo.workflow(flowamount,flowid)

模拟 a=1 and b=1 的查询

select * from dbo.workflow 
where flowid = 1 and flowamount = 1 

模拟 b=1 and a=1 的查询

select * from dbo.workflow 
where flowamount = 1 and flowid = 1 

可以看到,当表新建,还没有数据时,优化器根本不会去判断用不用索引,而是直接全表扫描。反正就一个数据页。

SQL 中判断条件的先后顺序,会引起索引失效吗?

 

当我们加点数据时,再看看反应:

这里不得不再提下 tally table 的用法,实在看不下去利用循环来生成测试数据的方法

DECLARE @BEGIN DATETIME = '2010-01-01'

                ,@END DATETIME = '2017-10-30'

DECLARE @INC INT ;

SELECT @INC = DATEDIFF(DAY,@BEGIN,@END)



; WITH 

    L0 AS ( 

            SELECT * FROM (VALUES(1),(2),(3)) AS T(C) )

,    L1 AS (

            SELECT a.C,b.C AS BC FROM L0 AS a cross join L0 AS b )

,    L2 AS (

            SELECT a.C,b.C AS BC FROM L1 AS a cross join L1 AS b )

,    L3 AS (

            SELECT a.C,b.C AS BC FROM L2 AS a cross join L2 AS b )

,    L4 AS (

            SELECT a.C,b.C AS BC FROM L3 AS a cross join L3 AS b )

,    L5 AS (

            SELECT a.C,b.C AS BC FROM L4 AS a cross join L4 AS b )

insert into  dbo.workflow (flowid,flowamount,flowcount)            

SELECT TOP 50000 RNK , RNK * 10, RNK + 20 

FROM 

(

SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RNK 

FROM L5

) M 

此时表里有5万条数据,再看上面两条查询的执行计划:

这儿模拟题目中的 idx(b,a) 索引结构

create index idx_amt_id on dbo.workflow(flowamount,flowid)

模拟 a=1 and b=1 的查询

select * from dbo.workflow 
where flowid = 1 and flowamount = 1 

模拟 b=1 and a=1 的查询

select * from dbo.workflow 
where flowamount = 1 and flowid = 1 
SQL 中判断条件的先后顺序,会引起索引失效吗?

 

很明显,都会走索引 idx(b,a) 这种模式,与 b 在前和 a 在前无关。优化器可以优化这部分表达式的重组。

但,是不是所有条件表达式都没有先后顺序要求呢?肯定不是

只有在相等条件判断时,先后顺序不重要,一旦有表达式用于非等判断,顺序就很重要了,如下:

select * from dbo.workflow 
where flowamount > 39 and flowid = 1 


select * from dbo.workflow 
where flowid = 1 and flowamount > 39  
SQL 中判断条件的先后顺序,会引起索引失效吗?

 

这里优化器提示(绿色字体部分),建立一个相等判断条件的索引在前,非等判断字段在后的索引 (flowid,flowamount)。所以本质上,索引结构中字段先后不受制于查询中相等判断条件表达式字段的顺序,而受制于非等条件判断表达式。即非等判断字段(flowamount>39)需要放在相等判断字段(flowid=1)的后面。

create index idx_id_amtr on dbo.workflow(flowid,flowamount)


select * from dbo.workflow 
where flowamount > 39 and flowid = 1 


select * from dbo.workflow 
where flowid = 1 and flowamount > 39  

再看两者的执行计划:

SQL 中判断条件的先后顺序,会引起索引失效吗?

 

这里就走了我们刚才新建的索引 idx_id_amtr

第二个问题,b=1 还会利用索引 idx(a,b)吗

在上面的示例中,建立 index(flowamount,flowid) 的索引,那么对应到要解决的问题,便是 where flowid = 1 会走 index(flowamount,flowid)的索引吗?

select * from dbo.workflow 
where  flowid = 1 
SQL 中判断条件的先后顺序,会引起索引失效吗?

 

由此可见 b=1 是不会利用索引 idx(a,b) 了。

注意,或许 oracle, MySQL, pg, 等其他数据库会有不同,大家可以尝试实际操作下,再一起来讨论。各自优化器的算法不同,优化略微有些诧异。不必过于纠结。



Tags:SQL   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
作者:雷文霆 爱可生华东交付服务部 DBA 成员,主要负责Mysql故障处理及相关技术支持。爱好看书,电影。座右铭,每一个不曾起舞的日子,都是对生命的辜负。 本文来源:原创投稿 *爱可生...【详细内容】
2021-12-24  Tags: SQL  点击:(6)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  Tags: SQL  点击:(12)  评论:(0)  加入收藏
场景描述:由于生产环境的表比较复杂,字段很多。这里我们做下简化,只为说明今天要聊的问题。有两张表 tab1,tab2: tab1 数据如下: tab2 数据如下: 然后给你看下,我用来统计 name=&#3...【详细内容】
2021-12-20  Tags: SQL  点击:(5)  评论:(0)  加入收藏
前言作为一名测试工程师,工作中在对测试结果进行数据比对的时候,或多或少要和数据库打交道的,要和数据库打交道,那么一些常用的 SQL 查询语法必须要掌握。最近有部分做测试小伙...【详细内容】
2021-12-14  Tags: SQL  点击:(15)  评论:(0)  加入收藏
概述以前参加过一个库存系统,由于其业务复杂性,搞了很多个应用来支撑。这样的话一份库存数据就有可能同时有多个应用来修改库存数据。比如说,有定时任务域xx.cron,和SystemA域...【详细内容】
2021-11-05  Tags: SQL  点击:(31)  评论:(0)  加入收藏
完整的SELECT查询 SELECT DISTINCT column, AGG_FUNC(column_or_expression), … FROM mytable JOIN another_table ON mytable.column = another_table.c...【详细内容】
2021-11-05  Tags: SQL  点击:(27)  评论:(0)  加入收藏
数据库对象是数据库的组成部分,常见的有以下几种:表(Table )、索引(Index)、视图(View)、图表(Diagram)、缺省值(Default)、规则(Rule)、触发器(Trigger)、存储过程(Stored Procedure)、 用户(User)等。命名规范是指数据库对象如数据库(SCH...【详细内容】
2021-11-04  Tags: SQL  点击:(37)  评论:(0)  加入收藏
1.1 什么是约束约束字面意思就是限制,比如我们每一个人的身份证号都是唯一的,不可能出现两个人,身份证是一样的,那么这里的唯一性我们就称之为一种约束,再比如:我们每个人都是有性...【详细内容】
2021-10-18  Tags: SQL  点击:(97)  评论:(0)  加入收藏
一、前言SQL JOIN是软件开发者的必会知识点,这些JOIN有什么区别和联系呢,本文来一一剖析。要了解SQL,其实我们需要了解下关系代数。为什么这么说呢?数据库系统合并数据的原理其...【详细内容】
2021-10-15  Tags: SQL  点击:(67)  评论:(0)  加入收藏
如图所示,我们已经在macOS中安装完成了MySQL 服务器。 Configuration配置信息,如图所示。 专栏 Java程序员的macOS手册 作者:软件架构 19.8币 12人已购 查看 但是,如何使用My...【详细内容】
2021-10-12  Tags: SQL  点击:(56)  评论:(0)  加入收藏
▌简易百科推荐
1增1.1【插入单行】insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values (&#39;开心朋朋&#39;,&#39;男&#39;,&#39;1980/6/15&#3...【详细内容】
2021-12-27  快乐火车9d3    Tags:SQL   点击:(1)  评论:(0)  加入收藏
最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用哪种写法,以及各种写法的优缺点,本文以一个简单的查询...【详细内容】
2021-12-23  linux上的码农    Tags:sql   点击:(9)  评论:(0)  加入收藏
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的HasorDB 是一个全功能数据库访问工具,提供对象映射、丰...【详细内容】
2021-12-22  GitHub精选    Tags:HasorDB   点击:(5)  评论:(0)  加入收藏
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22    51CTO  Tags:Liquibase   点击:(3)  评论:(0)  加入收藏
场景描述:由于生产环境的表比较复杂,字段很多。这里我们做下简化,只为说明今天要聊的问题。有两张表 tab1,tab2: tab1 数据如下: tab2 数据如下: 然后给你看下,我用来统计 name=&#3...【详细内容】
2021-12-20  Bald    Tags:SQL   点击:(5)  评论:(0)  加入收藏
前言知识无底,学海无涯,知识点虽然简单,但是比较多,所以将MySQL的基础写出来,方便自己以后查找,还有就是分享给大家。一、SQL简述1.SQL的概述Structure Query Language(结构化查...【详细内容】
2021-12-16  谣言止于独立思考    Tags:SQL基础   点击:(13)  评论:(0)  加入收藏
前言作为一名测试工程师,工作中在对测试结果进行数据比对的时候,或多或少要和数据库打交道的,要和数据库打交道,那么一些常用的 SQL 查询语法必须要掌握。最近有部分做测试小伙...【详细内容】
2021-12-14  柠檬班软件测试    Tags:SQL   点击:(15)  评论:(0)  加入收藏
话说C是面向内存的编程语言。数据要能存得进去,取得出来,且要考虑效率。不管是顺序存储还是链式存储,其寻址方式总是很重要。顺序存储是连续存储。同质结构的数组通过其索引表...【详细内容】
2021-12-08  小智雅汇    Tags:数据存储   点击:(17)  评论:(0)  加入收藏
概述DBConvert Studio 是一款强大的跨数据库迁移和同步软件,可在不同数据库格式之间转换数据库结构和数据。它将成熟、稳定、久经考验的 DBConvert 和 DBSync 核心与改进的现...【详细内容】
2021-11-17  雪竹聊运维    Tags:数据库   点击:(26)  评论:(0)  加入收藏
一、前言 大家好,我是小诚,《从0到1-全面深刻理解MySQL系列》已经来到第四章,这一章节的主要从一条SQL执行的开始,由浅入深的解析SQL语句由客户端到服务器的完整执行流程,最...【详细内容】
2021-11-09  woaker    Tags:SQL   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条