高性能MySql达尔文主义(六):常见索引类型的原理及其特点的介绍
高性能MySql进化论(六):常见索引类型的原理及其特点的介绍 众所周知,索引对于数据库性能的影响至关重要,但是索引为什么可以提高查询效率,以及索引的种类及其特点可能不是很清楚,本文将对常用的索引类型以及特点做一个简单的介绍 1为什么要使用索引 首先来
高性能MySql进化论(六):常见索引类型的原理及其特点的介绍众所周知,索引对于数据库性能的影响至关重要,但是索引为什么可以提高查询效率,以及索引的种类及其特点可能不是很清楚,本文将对常用的索引类型以及特点做一个简单的介绍
1 为什么要使用索引
首先来说一下索引为什么可以提高查询效率。普通查询的过程往往是通过整表的扫描来获得期望的结果,如果表的纪录非常的多,查询的效率肯定会很慢。而索引则会通过最大程度的降低扫描纪录的条数来提高效率,不同类型的索引往往会采取不同的策略来降低扫描的记录数,具体的策略将在后面进行描述。
首先看一个简单的例子,来说明索引的作用
在这个例子中使用了一张包含100,000条左右的字典表 ,比较是否包含索引的查询时间
mysql> select id,word, mean from dictionary where mean='DEFAULT2'; +--------+--------+----------+ | id | word | mean | +--------+--------+----------+ | 110003 |Random | DEFAULT2 | +--------+--------+----------+ 1 row inset (0.05sec) mysql> select id,word, mean from dictionary where word='Random'; +--------+--------+----------+ | id | word | mean | +--------+--------+----------+ | 110004 |Random | DEFAULR# | | 110003 |Random | DEFAULT2 | +--------+--------+----------+ 2 rows inset (0.00sec)
接下来看看为什么会时间上有所差别,通过执行计划可以看出,第一条语句执行了整表扫描,查询了110486条记录才得到想要的结果,而第二条语句使用了索引,只检索了2条记录就得到了想要的结果,这说明了索引的主要提速原理:查询的过程中减少扫描的记录数
mysql> explain select id,word, mean from dictionary wheremean='DEFAULT2'; +----+-------------+------------+-------+---------------+------+---------+------+--------+--------------------------+ | id |select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------+---------+------+--------+--------------------------+ | 1 | SIMPLE | dictionary | All | NULL | word | 135 | NULL | 110486 | Using where; Usingindex | +----+-------------+------------+-------+---------------+------+---------+------+--------+--------------------------+ 1 row inset (0.00 sec) mysql> explain select id,word, mean from dictionary where word='Random'; +----+-------------+------------+------+---------------+------+---------+-------+------+--------------------------+ | id |select_type | table | type |possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+-------+------+--------------------------+ | 1 | SIMPLE | dictionary | ref | word | word | 102 | const | 2| Usingwhere; Using index | +----+-------------+------------+------+---------------+------+---------+-------+------+--------------------------+ 1 row inset (0.00 sec)
2 索引的类型
在大多数的RDBMS中,索引的特性由存储引擎决定,不同的存储引擎在索引的实现上可能会采用不同的实现,B-Tree Index以及Hash Index是比较常用的两种索引。这两种索引使用的底层数据结构是不同的,所以这两种索引在使用的过程中也有各自的特点
2.1 B-Tree Index
B-Tree索引是一种使用相对广泛的索引类型,在很多数据库中 (ORACLE,MYSQL) 也将它作为默认的索引类型,这种索引采用B-Tree数据结构来存储数据。
B-tree是以排序的方式存储数据并允许以O(log n)的运行时间进行查找,顺序读取,插入和删除的数据结构。概括来说是一个节点可以拥有多于2个子节点的二叉查找树。在B-Tree中,内部(非叶子)节点可以拥有,预先设定范围数量内的多个子节点。当数据被插入或从一个节点中移除,它的子节点数量发生变化。
下面是B-Tree的结构图
上图说明了B-Tree的工作原理,在根节点中定义了叶子节点值的区间范围,叶子中存储了实际的值。当进行查找时,首先会使用条件值在根节点中选择一个合适叶子节点区间,然后再用条件值和叶子层某个区间内的叶子节点的值进行比较。
举个例子来说明其原理,例如 学生表中的学生ID是有序递增的,图中的Key1 是100,Key2是200.当需要查询一个ID为90的学生时会在最左侧的叶子链表中进行搜索,如果需要查询一个ID为130的学生时,会在中间的叶子链表中进行查找。这样的查询方式因为避免了全表扫描,所以效率会大大的提高。
有一点需要注意,当把B-Tree索引建立在多个字段上时,(例如 建立索引时顺序为 LastName, FirstName,BrithDay),则每个Key值都是LastName,FirstName,Brithday这样的数据结构,匹配的叶子节点值的过程是按照索引中定义的字段顺序来进行比较的,所以在使用索引的过程中必须按照这样的顺序来使用,否则索引将得不到正确使用(比如你在Where条件中的顺序是Brithday , LastName, FirstName)。
由于在B-Tree中存储的索引数据都是有序的,如果在B-Tree索引上执行Order by,排序的效率也会大大的提高。
B-Tree的工作原理决定了它对下面的查询方式有良好的支持:
(1) 全索引匹配- 匹配条件包含索引的所有字段,以及完全匹配其字段顺序
(2) 只匹配索引的第一列
(3) 只匹配第一列的前缀(右匹配),例如 “where lastName like Sun%”
(4) 第一列的范围查找 –例如 “where lastName between “Steve” and “Tony”
(5) 第一列全匹配,第二列前缀匹配
(6) 要求返回的值,是索引的子集,例如 select LastName, FristName,Brithday from Student where LastName like ”Tony”. 因为B-Tree中包含了要求的值,所以在这种情况下可以让数据的访问只发生在B-Tree中而避免对数据表的访问(Mysql中有个专门的名词叫“覆盖索引”)
同时B-Tree的工作原理也决定了在使用下面的查询方式时,索引的功效会受到影响:
(1) 查询条件没有从索引的第一列开始,例如 where firstname=”Eric” andbirthday=’2010-10-10’
(2) 没有顺序的使用索引中的列,例如 where lastname=”Tony” andbirthday=”2010-10-10”
(3) 由于使用了模糊匹配,导致了值使用了索引的部分字段,例如 where lastname=’tony’ andfirstname like ‘Robert%’ and birthday=’2010-10-10’, 在这里只用到了索引的lastname以及firstname字段,brithday被like 操作给屏蔽掉了
前面列出了B-Tree索引在使用的过程中的一些问题,这些问题说明查询条件中字段的顺序对索引的使用会有比较大的影响。所以在设计索引或者查询条件时要注意字段的顺序问题。有些时候可能还会建立多个字段相同但是顺序不同的索引来弥补这种顺序问题。
2.2 Hash索引
顾名思义,这种类型的索引采取Hash的数据结构来存储索引。结构图大概为
存储的时候会把key通过Hash函数计算,得到key的Hash值,再用这个Hash值做指针和数据库记录指针绑定在一起。选定一个好的Hash函数很重要,好的Hash函数可以使计算出的Hash值分布均匀,降低冲突,只有冲突减小了,才会降低Hash表的查找时间。在查询的过程大概会分为四步
(1) 根据查询条件生成一个Hash值例如 在name 上建立了一个hash索引,且在查询条件where name=’John Smith’ 中’John Smith’的hash值是02.
(2) 用02的Hash值到Hash索引表中找到对应的Bucket
(3) 使用步骤(2)中Bucket包含的表指针(521-1234)找到数据库中的某条记录
(4) 由于不同的name可能会有相同的Hash值,所以最后一步需要比较’John Smith’是否和已经找到的数据库记录的name相同,相同就返回当前记录,否则返回步骤2,寻找另外一条数据记录再进行匹配,直到找到对应的记录
Hash 索引结构的特殊性,决定了其检索效率非常的高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。
(1)Hash 索引仅仅能满足"=","IN"和""查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
值得一提的是,多数的数据库管理系统默认的索引类型为B-Tree(Oracle,Mysql-InnoDB),所以想要使用Hash索引的话,必须显示的设定其为Hash索引。很多比较智能的数据存储引擎(例如 Mysql 的InnoDB)会采用一种叫做“自适应Hash索引”来提高查询效率,这种机制的工作原理是 当存储引擎使用B-Tree的索引类型时,如果发现某个索引的值被检索的非常频繁时,存储引擎会自动把该值当做Hash处理,以此来提高B-Tree的效率。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

在 Docker 中啟動 MySQL 的過程包含以下步驟:拉取 MySQL 鏡像創建並啟動容器,設置根用戶密碼並映射端口驗證連接創建數據庫和用戶授予對數據庫的所有權限

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

優雅安裝 MySQL 的關鍵在於添加 MySQL 官方倉庫。具體步驟如下:下載 MySQL 官方 GPG 密鑰,防止釣魚攻擊。添加 MySQL 倉庫文件:rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm更新 yum 倉庫緩存:yum update安裝 MySQL:yum install mysql-server啟動 MySQL 服務:systemctl start mysqld設置開機自啟動

在 CentOS 上安裝 MySQL 涉及以下步驟:添加合適的 MySQL yum 源。執行 yum install mysql-server 命令以安裝 MySQL 服務器。使用 mysql_secure_installation 命令進行安全設置,例如設置 root 用戶密碼。根據需要自定義 MySQL 配置文件。調整 MySQL 參數和優化數據庫以提升性能。

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。
