从上至下优化

看过一篇文章,印象深刻,里面将数据库查询优化分为四个大的方向

  • 使用钞能力——给DB服务器加物理配置,内存啊,CPU啊,硬盘啊,全上顶配
  • 替换存储系统——根据实际的业务情况选择不同的存储数据库,比如用ES做全文检索
  • 优化存储结构——比如采用分库分表,CQRS(命令查询职责分离),分布式缓存,历史数据归档,数据序列化等
  • 查询语句的优化——增加数据库索引命中率,定期清理数据库索引碎片等

    从上到下成本依次递减,性价比依次升高,今天咱们聊聊Sql Server中基于索引的“查询语句的优化”

索引数据结构

谈到索引,咱们避免不了会想到索引的存储数据结构,目前大多数RDBS(关系型数据库系统)采用B+树来存储索引数据,如果还不是特别清楚啥是B+树的话,这里有传送门点击这里

这里简单概括一下B+树的几个特点:

  • 每个节点可以存储多个元素
  • 所有的非叶子节点只存储关键字信息
  • 所有具体数据都存在叶子结点中
  • 所有的叶子结点中包含了全部元素的信息
  • 所有叶子节点之间都有一个链指针

索引分类

聚集索引

  • 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。 索引定义中包含聚集索引列。 每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。
  • 只有当表包含聚集索引时,表中的数据行才按排序顺序存储。 如果表具有聚集索引,则该表称为聚集表。 如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。

可以简单理解为数据表中的数据按照既定的顺序进行存储,而这个用来排序的字段就是聚集索引。也可以理解为一个个由Key-Value组成的元素分布在一棵B+树上,Key对应的就是索引,Value对应的就是具体的数据行。

非聚集索引

  • 非聚集索引具有独立于数据行的结构。 非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针
  • 从非聚集索引中的索引行指向数据行的指针称为行定位器。 行定位器的结构取决于数据页是存储在堆中还是聚集表中。 对于堆,行定位器是指向行的指针。 对于聚集表,行定位器是聚集索引键。

大白话就是非聚集索引中存储的Key-Value,其中Key跟聚集索引一样是索引列,Value根据表是否存在聚集索引来进行区分,如果存在则Value为指向聚集索引键(也就是聚集索引的Key)的指针,不存在,则Value为指向表中数据行的指针。

查询优化

索引命中规则之最左匹配原则

众所周知,我们通常会在高频的where条件所用的字段上建立相关索引,那么我们建立索引以后我们的where查询条件是否命中索引呢?

CREATE NONCLUSTERED INDEX IDEMO ON DEMOTABLE (A ASC,B ASC,C ASC,D ASC);

如上,在表DEMOTABLE中用A,B,C,D四个字段创建了非聚集索引,首先列A必须出现在查询条件中即(A组合),剩下的依次可以为,A,B组合,A,B,C组合,A,B,C,D组合,类似下面这样:

SELECT E,F,G FROM DEMOTABLE WHERE A=1
SELECT E,F,G FROM DEMOTABLE WHERE A=1 AND B=2
SELECT E,F,G FROM DEMOTABLE WHERE A=1 AND B=2 AND C=3
SELECT E,F,G FROM DEMOTABLE WHERE A=1 AND B=2 AND C=3 AND D=4
//不会命中索引
SELECT E,F,G FROM DEMOTABLE WHERE B=2 AND C=3 AND D=4
//部分命中索引,只有条件A=1会命中
SELECT E,F,G FROM DEMOTABLE WHERE A=1 AND C=3 AND D=4

索引之覆盖索引

何为覆盖索引?

CREATE NONCLUSTERED INDEX IDEMO ON DEMOTABLE (A ASC,B ASC,C ASC,D ASC) INCLUDE(E,F,G);

上面所建的非聚集索引以上一个创建语句后面多了一个INCLUDE语句,这样做可以减少索引命中以后查询相关列时的回表操作,何谓回表?之前我们讲过在非聚集索引的叶子节点上存放了对应聚集索引的指针,查询在命中非聚集索引的以后要查询非索引列时会根据这个指针去聚集索引上查找相关列,这个动作就是回表;如果我们的非聚集索引上INCLUDE了要查询的列,就可以减少相关查询的回表操作,从而提高查询性能。像下面这条语句就可以完美的规避回表查询。

SELECT E,F,G FROM DEMOTABLE WHERE A=1 AND B=2 AND C=3 AND D=4

索引碎片

索引在建立过程中随着数据量的增加,索引碎片也会越来越多,从而导致即使在索引命中的情况下查询性能可能也不是特别理想,那这些碎片是怎么产生的呢?

  • 外部碎片

新的索引在插入的时候与旧的索引在物理存储位置上不连续,这就产生了外部碎片。

  • 内部碎片

新的索引在插入的时候导致因为索引所占空间大小的变化导致同一页上本可以存储3个索引,现在只能存下2个索引,存储2个索引以后剩下的空间就是内部碎片。

如何处理索引碎片呢?
  • 索引碎片已经很多的情况下

    这种情况我们可以采用索引重新生成或索引重新组织,当然一般来说线上环境都有专门的DBA负责这些事宜,我们只需要知道有这些处理方式就好。
  • 在创建索引的时候

    创建索引时我们可以根据实际的业务场景和索引字段所存信息的大小来适当的添加填充因子(0-100),也可以一定程度上减少索引碎片的产生。如果你还不清楚填充因子的话,可以看看这个

文章就到这里,如有不对的地方,欢迎评论区留言指正,感谢!!

SQL Server查询优化的更多相关文章

  1. SQL Server 查询优化 索引的结构与分类

    一.索引的结构 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情 ...

  2. SQL Server查询优化方法(查询速度慢的原因很多,常见如下几种) .

    今天看到一位博友的文章,觉得不错,转载一下,希望对大家有帮助,更多文章,请访问:http://blog.haoitsoft.com 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺 ...

  3. SQL Server查询优化器的工作原理

    SQL Server的查询优化器是一个基于成本的优化器.它为一个给定的查询分析出很多的候选的查询计划,并且估算每个候选计划的成本,从而选择一个成本最低的计划进行执行.实际上,因为查询优化器不可能对每一 ...

  4. SQL Server查询优化中的两个选项

    本文中,我们将介绍两个SQL Server中的可用概念,它们是使用SQL Server时值得注意的技术. 1.        OPTIMIZE FOR Unknown SQL Server 2005版 ...

  5. MS SQL Server查询优化方法 查询速度慢的原因很多,常见如下几种

    1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大 ...

  6. SQL Server 查询优化器运行方式

    一.结合实际,谈索引使用的误区 理论的目的是应用.虽然我们刚才列出了何时应使用聚集索引或非聚集索引,但在实践中以上规则却很容易被忽视或不能根据实际情况进行综合分析.下面我们将根据在实践中遇到的实际问题 ...

  7. 深入浅出的 SQL Server 查询优化

    目前网络数据库的应用已经成为最为广泛的应用之一了,并且关于数据库的安全性,性能都是企业最为关心的事情.数据库渐渐成为企业的命脉,优化查询就解决了每个关于数据库应用的性能问题,在这里microsoft ...

  8. SQL Server查询优化指南

    1.尽量不要使用is null,否则将导致引擎放弃使用索引而进行全表扫描.2.char是固定长度,速度快,但占空间,varchar不固定长度,不占空间,但速度慢.3.能使用数字类型就不要使用字符,查询 ...

  9. SQL Server 存储中间结果集

    在SQL Server中执行查询时,有一些操作会产生中间结果集,例如:排序操作,Hash Join和Hash Aggregate操作产生的Hash Table,游标等,SQL Server查询优化器使 ...

随机推荐

  1. 好客租房15-jsx中的条件渲染

    jsx中的条件渲染 场景:loding效果 条件渲染:根据条件渲染特定的jsx结构 可以使用if/else或者三元运算符和逻辑和运算符实现 //导入react import React from &q ...

  2. css属性补充与JS数据类型

    目录 溢出属性(overflow) 定位(position) z-index属性 opacity不透明度 JavaScript简介 变量与注释 数据类型 数值(Number) 字符串(String) ...

  3. RabitMQ 简介

    每日一句 The secret of being miserable is to have leisure to bother about whether you are happy or not. ...

  4. 腾讯产品快速尝鲜,蓝鲸智云社区版V6.1灰度测试开启

    这周小鲸悄悄推送了社区版V6.1(二进制部署版本,包含基础套餐.监控日志套餐),没过一天就有用户来问6.1的使用问题了.小鲸大吃一鲸,原来你还是爱我的. ![请添加图片描述](https://img- ...

  5. vs 快速定位文件

    在进行web开发时,我们经常需要在文件之间进行切换,每次在VS的解决方案中找文件然后打开 非常浪费时间,有没有比较快捷点的方法呢? 1.使用  ReSharper 插件 ReSharper 插件可以在 ...

  6. 工具分享:清理 Markdown 中没有引用的图片

    前言: 之前,我写笔记的工具一直都是 notion,而且没有写博客的习惯.但是一是由于 notion 的服务器在国外,有时候很不稳定:二是由于 notion 的分享很不方便,把笔记分享给别人点开链接之 ...

  7. windiws下安装Composer

    1.先下载Composer-Setup.exe,下载地址:下载Composer .会自动搜索php.exe的安装路径,如果没有,就手动找到php路径下的php.exe. 2.在PHP目录下,打开php ...

  8. C语言学习之我见-strncpy()字符串复制函数(可控制范围)

    strncpy()函数,用于两个字符串值的复制. (1)函数原型 char *strncpy(char * _Dest,const char * _Source,size_t _Count); (2) ...

  9. 【react】什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行

    壹 ❀ 引 我在[react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?一文中,介绍了虚拟dom的概念,以及react中虚拟dom的使用场景 ...

  10. Elasticsearch 在地理信息空间索引的探索和演进

    vivo 互联网服务器团队- Shuai Guangying 本文梳理了Elasticsearch对于数值索引实现方案的升级和优化思考,从2015年至今数值索引的方案经历了多个版本的迭代,实现思路从最 ...