前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >重学 SQL(九)

重学 SQL(九)

作者头像
1ess
发布2021-10-29 17:24:07
3390
发布2021-10-29 17:24:07
举报
文章被收录于专栏:0x7c00的专栏

重学 SQL(九)

發佈於 2020-08-24

本篇,我们介绍一个对于大型或高并发数据库影响非常有大的知识 —— 索引。了解它是如何工作的以及它为何能提升性能。 点击下载创建本章所用数据库脚本

Index

索引实际上是数据库用于快速检索数据的数据结构。如果没有索引,数据库会扫描每条记录。通过索引可以快速找到对应记录,这比遍历整个表的数据要高效得多。

索引的缺点:

  1. 增加数据库大小,因为索引要和表一起保存
  2. 增删改数据时,MySQL 会自动更新索引,影响当前操作效率,所以我们只给特别重要的查询增加索引

注意: 我们不要根据表来创建索引,而是根据查询内容来创建。给设计好的表增加索引就像解决了不存在的问题一样,所以不要盲目地给某一列添加索引。

在具体实现上,索引通常以二叉树的方式保存的。

创建索引

我们先来观察一个简单的搜索。

代码语言:javascript
复制
EXPLAIN SELECT customer_id
FROM customers
WHERE state = 'CA';

type

rows

ALL

1010

如果显示 type 字段为 ALL,则说明本次查询为全表扫描,rows 为扫描的记录数。 然后我们对 state 列创建索引:

代码语言:javascript
复制
CREATE INDEX idx_state ON customers (state);

创建好索引之后,我们再次执行简单查询,观察一下有什么不同:

代码语言:javascript
复制
EXPLAIN SELECT customer_id
FROM customers
WHERE state = 'CA';

type

key

rows

ref

idx_state

112

查看索引

代码语言:javascript
复制
SHOW INDEXES IN customers;

Key_name

Column_name

Index_type

PRIMARY

customer_id

BTREE

idx_state

state

BTREE

主键索引又称为聚合索引(Clustered Index),只要我们给表添加了主键,MySQL 就会自动为其创建索引,每个表最多只能有一个聚合索引。其余索引又称为从属索引(Secondary Index)。

代码语言:javascript
复制
SHOW INDEXES IN orders;

Key_name

Column_name

Index_type

PRIMARY

customer_id

BTREE

fk_orders_customers_idx

customer_id

BTREE

fk_orders_shippers_idx

shipper_id

BTREE

fk_orders_order_statuses_idx

status

BTREE

MySQL 也会自动为外键创建索引,这样我们就可以快速连接表了。

前缀索引

如果要创建的索引是字符串类型,索引会占用大量磁盘空间,我们知道小索引更好,他们可以载入内存。所以我们不用将这列的所有字符都放入索引中,只需要索引前几个字符。

代码语言:javascript
复制
CREATE INDEX idx_lastname ON customers (last_name(20));
如何找到最佳索引字符数
代码语言:javascript
复制
-- 首先确定总记录数
SELECT COUNT(*) FROM customers;
-- 1010

-- 确定采用多大字符数作为索引
SELECT
    COUNT(DISTINCT LEFT(last_name, 1)),
    COUNT(DISTINCT LEFT(last_name, 5)),
    COUNT(DISTINCT LEFT(last_name, 10))
FROM customers;
-- 25 966 996

我们观察发现,采用 5 个字符长度就可以区分绝大多数姓氏了。

全文索引

在 MySQL 以及其他数据库中,都有一个叫做全文索引的索引类型。用这种索引来完成复杂和有弹性的文字检索。 这种索引和传统索引有很大不同,他们包含这个字符串,他会去掉所有副词,如: in、on、the 等等。

代码语言:javascript
复制
SELECT *
FROM posts
WHERE 
    title LIKE '%react redux%' OR
    body LIKE '%react redux%';

如果没有索引,随着文章的增多,查询会越来越慢。这种需求下,我们就可以使用全文索引。

代码语言:javascript
复制
CREATE FULLTEXT INDEX idx_title_body ON posts (title, body);

接下来,我们使用与全文索引的匹配:

代码语言:javascript
复制
SELECT 
    *,
    MATCH(title, body) AGAINST('react redux')
FROM posts
WHERE 
    MATCH(title, body) AGAINST('react redux');

这样以任意次序,任意词分隔的数据都可以被检索出来。 全文索引还有一个好处是可以计算出相关度。相关值是一个 0 - 1 之间的浮点数。 全文索引默认是自然语言模式,还可以设置为布尔模式:

代码语言:javascript
复制
SELECT *
FROM posts
WHERE 
    MATCH(title, body) AGAINST('react -redux +form' IN BOOLEAN MODE);

减号表示禁止包含该词语,加号表示必须包含该词语。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Index
    • 创建索引
      • 前缀索引
        • 如何找到最佳索引字符数
      • 全文索引
      相关产品与服务
      云数据库 SQL Server
      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档