SQL Server的Descending Indexes降序索引

SQL Server的Descending Indexes降序索引

1、建立测试环境

测试环境:SQL Server 2012

表结构如下

USE [test]
GO

CREATE TABLE [dbo].[tt8](
    [id] INT IDENTITY(1,1) NOT NULL,
    [win_num] [int] NOT NULL DEFAULT ((0)),
    [lost_num] [int] NOT NULL   DEFAULT ((0)),
    [draw_num] [int] NOT NULL  DEFAULT ((0)),
    [offline_num] [int] NOT NULL   DEFAULT ((0)),
    [login_key] [nvarchar](50) NULL
 CONSTRAINT [PK_user_T] PRIMARY KEY CLUSTERED
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

插入测试数据

DECLARE @i INT;
DECLARE @sql NVARCHAR(MAX);
SET @i = 1;
WHILE @i  9999
    BEGIN
        SET @sql = 'INSERT  INTO [dbo].[tt8]
        (
          [win_num] ,
          [lost_num] ,
          [draw_num] ,
          [offline_num] ,
          [login_key]

        )
VALUES  (
        ''' + CAST(@i AS NVARCHAR(3000)) + ''' ,
        ''' + CAST(@i AS NVARCHAR(3000)) + ''' ,
        ''' + CAST(@i AS NVARCHAR(3000)) + ''' ,
            ''' + CAST(@i AS NVARCHAR(3000)) + ''' ,
            ''' + CAST(@i AS NVARCHAR(3000)) + '''

        );';
        EXEC ( @sql );
        SET @i = @i + 1;

    END;

2、构建查询语句

查询语句如下,可以看到这个是组合字段排序,要求是:按照draw_num值正序,对于相同的draw_num值,按照win_num值倒序

select top 10 * from [dbo].[tt8] order by  [draw_num] asc,[win_num] desc

根据查询语句建一个非聚集索引

CREATE NONCLUSTERED INDEX [IX_tt8_draw_numwin_num] ON [dbo].[tt8]
(
    [draw_num] ASC,
    [win_num] ASC

)WITH (online= ON) ON [PRIMARY]
GO

建了索引之后,执行计划如下,可以看到无法用到刚才建的索引,因为建索引时候,两个字段的排序顺序都是单向遍历的,统一升序或统一降序

SQL Server的Descending Indexes降序索引

3、建索引

那么,建索引时候能不能按照查询语句的顺序,[draw_num] 升序,[win_num] 降序呢?

答案是可以的,删除刚才建的索引,再建一个新索引

DROP INDEX [IX_tt8_draw_numwin_num]    ON [tt8]

CREATE NONCLUSTERED INDEX [IX_tt8_draw_numwin_num]   ON [dbo].[tt8]
(
    [draw_num] ASC ,
    [win_num] DESC )  WITH ( ONLINE = ON ) ON [PRIMARY]
GO

建了索引之后,索引大概是这样,第一个字段升序,第二个字段降序

SQL Server的Descending Indexes降序索引

再查询一次,执行计划如下,可以看到这次利用到索引

SQL Server的Descending Indexes降序索引

通过这个例子说明,对于组合字段排序的语句,当多个字段排序顺序不一致的时候,只建单个字段的索引是无法利用到索引的,例如下面只建一个[draw_num] 字段的索引是无法利用到[IX_tt8_draw_num]索引的

CREATE NONCLUSTERED INDEX [IX_tt8_draw_num]   ON [dbo].[tt8]
(
    [draw_num] ASC
)  WITH ( ONLINE = ON ) ON [PRIMARY]
GO

必须要建排序字段的组合索引,并且索引字段的排序要跟查询语句一致,这种索引在Oracle里面叫Descending Indexes

总结

Descending Indexes这个特性在SQL Server和Oracle的早期版本已经支持,在MySQL里面只有MySQL8.0才支持

所以有时候,还是商业数据库比较强大

参考文章:

https://www.mssqltips.com/sqlservertip/1337/building-sql-server-indexes-in-ascending-vs-descending-order/

如有不对的地方,欢迎大家拍砖o(∩_∩)o

本文版权归作者所有,未经作者同意不得转载。

Original: https://www.cnblogs.com/lyhabc/p/10790266.html
Author: 桦仔
Title: SQL Server的Descending Indexes降序索引

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/590813/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 20 年老程序员告诉你的 20 条编码原则

    我从 1999 年就开始了编程生涯,到今年已经有 20 多年了。我先是从 Basic 开始,很快转到了 Pascal 和 C 语言,然后又学习了面向对象编程语言 Delphi 和 …

    数据库 2023年6月14日
    0136
  • Spring中常见的注解

    1.组件注解 @Controller @Service @Repository @Component —标注一个类为Spring容器的Bean @Configratio…

    数据库 2023年6月11日
    0109
  • 面试记录

    JVM线程属于用户态还是内核态 当进程运行在ring3级别时为用户态,ring0级别时为内核态 有些操作需要有内核权限才能进行,那么有三种由用户态切换到内核态的情况: 系统调用:操…

    数据库 2023年6月16日
    0151
  • String类常用的API

    String类常用API总结及注意事项 String类常用的API 字符串内容的比较: 注意: 不能使用 == 去比较两个字符串的内容。原理:比较的是字符串的地址。(如果两个字符串…

    数据库 2023年6月16日
    0131
  • Redis

    一、了解 1、Nosql概述(同sql的区别) 1、存储方式 SQL&…

    数据库 2023年6月6日
    0121
  • 多线程

    多线程使用Callable实现多线程 多线程第三种创建方式 定义一个任务类,实现Callable接口,结合FutureTask完成 交给Thread处理,重写call方法 目标:学…

    数据库 2023年6月16日
    0142
  • 数据库操作命令

    MySQL Key Command 清屏 (滚屏 ) 登录 切换数据库 查看数据库 查看表 查看表结构 退出 帮助 Key Command 查看可用字符集 查看默认字符集 设置默认…

    数据库 2023年5月24日
    0112
  • MySQL面试整理

    索引的目的在于提高查询效率,以及添加约束; 常用的索引有: 普通索引,唯一索引,联合索引,全文索引,空间索引… 唯一索引 有两个分类 分别是:主键索引和唯一索引 联合索…

    数据库 2023年6月9日
    0226
  • SQLZOO练习四–SUM and COUNT(聚合函数)

    4、count the big countries 计算有多少个国家,面积大于1000000 How many countries have an area of at least…

    数据库 2023年6月16日
    0123
  • 对实体 “xxxxxx” 的引用必须以 ‘;’ 分隔符结尾。

    在配置才c3p0-config.xml文件时,向在Mysql连接的url中加入属性,结果报错 原因是因为 & 符号在XML格式的文件中需要进行转义 只需要把 & 换…

    数据库 2023年6月6日
    0123
  • .NET nhibernate 添加新的表运行报is not mapped的问题

    最后在修改一个.NET nhibernate的项目,按照原来的表添加了一个实体和一个hbm.xml的配置文件,写好所有业务代码以后运行报以下错误 NoAuthorizationSi…

    数据库 2023年6月9日
    0132
  • Redis-持久化

    因为Redis是内存操作,意味着掉电就GG, 所以为了保证异常重启等问题后能尽快恢复服务,还是需要一定的持久化机制来保证。Redis提供了两种持久化机制: AOF Append O…

    数据库 2023年6月11日
    0146
  • SpringMVC完整版详解

    1.回顾MVC 1.1什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。 是将业务逻辑、数据、显示分离的方法来组…

    数据库 2023年6月16日
    0112
  • 深入汇编指令理解Java关键字volatile

    volatile是什么 volatile关键字是Java提供的一种轻量级同步机制。它能够保证可见性和有序性,但是不能保证原子性 可见性 对于volatile的可见性,先看看这段代码…

    数据库 2023年6月16日
    0122
  • 数字加密

    java中使用数组对数字进行简单的加密。 数字加密 需求: 某系统的数字密码:比如1983,采用加密方式进行传输,规则如下:先得到每位数,然后每位数都加上5,再对10取余,最后将所…

    数据库 2023年6月16日
    0215
  • Redis的Java客户端

    Redis 的 Java 客户端 Jedis 优点:以 Redis 命令作为方法名称,学习成本低廉,简单且实用 缺点:Jedis 的实例是线程不安全的,在多线程的环境下需要基于线程…

    数据库 2023年6月16日
    0128
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球