数据库优化(二)—— MySQL索引优化

目录

  • MySQL的索引优化

    • 一、MySQL 5.7的初始化配置
    • 二、MySQL配置文件
      • 1、配置
      • 2、配置文件作用
    • 三、多实例
      • 1、创建相关的目录
      • 2、创建实例的配置文件
      • 3、初始化
      • 4、授权
      • 5、启动实例
      • 6、查看启动状况
      • 7、测试
      • 8、配置启动脚本
      • 9、开机自启
      • 10、设定mysql密码
      • 11、忘记密码
    • 四、数据类型
      • 1、整型
      • 2、字符串类型
      • 3、时间类型
      • 规范
    • 五、索引
      • 1、索引作用
      • 2、索引种类
      • 3、Btree 分类
      • 4、聚集索引和辅助索引的对比
    • 六、MySQL索引管理
      • 1、创建索引(辅助索引)
      • 2、删除索引
      • 3、查看创建的索引
      • 4、前缀索引
      • 5、唯一键索引
      • 6、覆盖索引(联合索引)
    • 七、explain(desc)命令的应用
      • 1、字段
      • (2)Extra
      • (3)其他字段
    • 八、建立索引规范
    • 九、建立索引原则
    • 十、不走索引的情况
    • 十一、压力测试

MySQL的索引优化

一、MySQL 5.7的初始化配置

/usr/local/mysql/bin/mysqld --initialize-insecure  --user=mysql --datadir=/opt/mysql/data --basedir=/opt/mysql

二、MySQL配置文件

1、配置

vim /etc/my.cnf
    [mysqld]
    basedir = /opt/mysql
    datadir = /opt/mysql/data
    port = 3306
    user = mysql
    socket = /tmp/mysql.sock
    log_error = /var/log/mysql.log
    [mysql]
    socket=/tmp/mysql.sock

2、配置文件作用

(1)影响服务端的启动

标签:[mysqld]   [mysqld_safe]   [server]   ...
  • 必须配置的内容
[mysqld]
basedir = /opt/mysql
datadir = /opt/mysql/data
user = mysql
socket = /tmp/mysql.sock
port = 3306
server_id = 6

(2)影响客户端的连接

标签:[client]  [mysql]    [mysqldump] ...
  • 配置内容
[mysql]
socket = /tmp/mysql.sock

(3)影响初始化

三、多实例

端口号为3307、3308、3309

1、创建相关的目录

mkdir -p /data/330{7..9}/data

2、创建实例的配置文件

cat>> /data/3307/my.cnf<<EOF
    [mysqld]
    basedir=/opt/mysql
    datadir=/data/3307/data
    user=mysql
    socket=/data/3307/mysql.sock
    port=3307
    server_id=3307
    EOF

cp /data/3307/my.cnf /data/3308
cp /data/3307/my.cnf /data/3309 

sed -i ‘s#3307#3308#g‘ /data/3308/my.cnf
sed -i ‘s#3307#3309#g‘ /data/3309/my.cnf

3、初始化

# 初始化数据
mysqld --initialize-insecure  --user=mysql --datadir=/data/3307/data --basedir=/opt/mysql
mysqld --initialize-insecure  --user=mysql --datadir=/data/3308/data --basedir=/opt/mysql
mysqld --initialize-insecure  --user=mysql --datadir=/data/3309/data --basedir=/opt/mysql

4、授权

chown -R mysql.mysql /data/*

5、启动实例

mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &

6、查看启动状况

netstat -lnp|grep 330

7、测试

mysql -S /data/3307/mysql.sock
mysql -S /data/3308/mysql.sock
mysql -S /data/3309/mysql.sock

8、配置启动脚本

cat >> /etc/systemd/system/mysqld3307.service <<EOF
    [Unit]
    Description=MySQL Server
    Documentation=man:mysqld(8)
    Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
    After=network.target
    After=syslog.target
    [Install]
    WantedBy=multi-user.target
    [Service]
    User=mysql
    Group=mysql
    ExecStart=/opt/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
    LimitNOFILE = 5000
    EOF

cp  /etc/systemd/system/mysqld3307.service   /etc/systemd/system/mysqld3308.service
cp  /etc/systemd/system/mysqld3307.service   /etc/systemd/system/mysqld3309.service 

sed -i ‘s#3307#3308#g‘   /etc/systemd/system/mysqld3308.service
sed -i ‘s#3307#3309#g‘   /etc/systemd/system/mysqld3309.service

9、开机自启

[[email protected] ~]# systemctl start mysqld3307
[[email protected] ~]# systemctl start mysqld3308
[[email protected] ~]# systemctl start mysqld3309
[[email protected] ~]# netstat -lnp|grep 330
tcp6       0      0 :::3307                 :::*                    LISTEN      3773/mysqld
tcp6       0      0 :::3308                 :::*                    LISTEN      3808/mysqld
tcp6       0      0 :::3309                 :::*                    LISTEN      3843/mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      2721/mysqld
[[email protected] ~]# systemctl stop mysqld3309
[[email protected] ~]# systemctl stop mysqld3308
[[email protected] ~]# systemctl stop mysqld3307

[[email protected] ~]# systemctl enable  mysqld3307
[[email protected] ~]# systemctl enable  mysqld3308
[[email protected] ~]# systemctl enable  mysqld3309

10、设定mysql密码

mysqladmin -uroot -p password 123

11、忘记密码

# root等用户信息存在mysql.user表中
select user,authentication_string,host from mysql.user;

# 1.停数据库
/etc/init.d/mysqld stop
# 2.启动数据库为无密码验证模式
mysqld_safe --skip-grant-tables --skip-networking  &
update mysql.user set authentication_string=PASSWORD(‘456‘) where user=‘root‘ and host=‘localhost‘;
/etc/init.d/mysqld restart

[[email protected] ~]# mysql -uroot -p123
[[email protected] ~]# mysql -uroot -p456

四、数据类型

1、整型

int
最多存10位数字:-2^31 ~ 2^31-1

2、字符串类型

char       定长,存储效率高,但是对于变化多的字段,空间浪费高
varchar    变长,存储时判断长度,存储会有额外开销,按需分配空间
enum       枚举类型

3、时间类型

datetime    日期+时间
date        日期
timestamp   时间戳
time      时间

规范

  • 少于10位数,用 int;大于10位用 char
  • char 和 varchar 选择时,字符长度一定不变用 char ;字符长度改变的用 varchar

    在使用可变的数据类型时,将来使用不同的数据类型,对于索引树的高度会有影响

  • 选择合适的数据类型
  • 合适长度

五、索引

1、索引作用

优化查询,select 查询有三种情况:缓存查询(不在mysql中进行数据查询),全表扫描,索引扫描

2、索引种类

  • Btree(btree b+tree b*tree)
  • Rtree
  • HASH
  • FullText

3、Btree 分类

聚集索引:基于主键,自动生成的,一般是建表时创建主键。如果没有主键,自动选择唯一键做为聚集索引

辅助索引:人为创建的(普通,覆盖)

唯一索引:人为创建(普通索引,聚集索引)

4、聚集索引和辅助索引的对比

  • 聚集索引:叶子结点,按照主键列的顺序,存储的整行数据,就是真正的数据页
  • 辅助索引: 叶子结点,列值排序之后,存储到叶子结点+对应的主键的值,便于回表查询

六、MySQL索引管理

1、创建索引(辅助索引)

alter table blog_blog add key idx_name(name);
# 或者
create index index_name on blog_blog(name);

2、删除索引

alter table blog_blog drop key idx_name(name);
# 或者
drop index index_name on blog_blog(name);

3、查看创建的索引

show index from blog_blog;

4、前缀索引

# select count(*),substring(password,1,20) as sbp  from blog_userinfo group by sbp;
alter table blog_userinfo add index idx(password(10));

5、唯一键索引

alter table blog_blog add unique key uni_name(name);

6、覆盖索引(联合索引)

作用:不需要回表查询,不需要聚集索引,所有的数据都从辅助索引中获取

alter table t1 add index idx_abc(age,box,electric);   # 第一个为主要条件,第一条件,查询量多的条件放前面,有序

# 查询的时候,where后面条件不是age放首位的条件,都不走联合索引

七、explain(desc)命令的应用

获取优化器选择后的执行计划

 oldguo [world]>explain select * from city where countrycode=‘CHN‘\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: city
         type: ref
possible_keys: CountryCode,idx_co_po
          key: CountryCode
      key_len: 3
          ref: const
         rows: 1
        Extra: Using index condition
1 row in set (0.00 sec)

1、字段

(1)type —— 查询类型(上至下性能增加)

  • 判断是全表扫描还是索引扫描(ALL是全表扫描,其他的是索引扫描)
  • 判断是哪一种类的索引扫描

    ALL:全表扫描 —— select * from t1;

    Index:全索引扫描 —— desc select countrycode from city ;

    range:索引范围扫描 —— where > < >= <= in or between and like ‘CH‘

    select * from city where country in (‘China‘,‘USA‘)s

    ref:辅助索引等值查询 —— in与or替换为union的查询效率会提高

    select * from city where country=‘China‘
    union all
    select * from city where country=‘USA‘

    eq_ref:多表连接查询(join on )

    constsystem :主键或唯一键等值查询

(2)Extra

using filesort:文件排序,可以进行优化

将order by、group by、distinct 后面的列和where条件列建立联合索引

(3)其他字段

possible_keys: CountryCode,idx_co_po      ---->可能会走的索引
key: CountryCode                          ---->真正走的索引
type: ref                                 ---->索引类型
Extra: Using index condition              ---->额外信息

八、建立索引规范

1、建表时一定要有主键,如果相关列可以作为主键,做一个无关列

2、选择唯一性索引

唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。

主键索引和唯一键索引,在查询中使用是效率最高的。

注意:如果重复值较多,可以考虑采用联合索引

3、为经常需要排序、分组和联合操作的字段建立索引

经常需要ORDER BY、GROUP BY,join on等操作的字段,排序操作会浪费很多时间。

如果为其建立索引,可以有效地避免排序操作。

4、为常作为where查询条件的字段建立索引

如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,

为这样的字段建立索引,可以提高整个表的查询速度。

5、尽量使用前缀来索引

如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索

会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。

6.限制索引的数目
索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。
修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。

7.删除不再使用或者很少使用的索引(percona toolkit)
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理
员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。

8.大表加索引,要在业务不繁忙期间操作

九、建立索引原则

(1) 必须要有主键,如果没有可以做为主键条件的列,创建无关列

(2) 经常做为where条件列 order by group by join on的条件(业务:产品功能+用户行为)

(3) 最好使用唯一值多的列作为索引,如果索引列重复值较多,可以考虑使用联合索引

(4) 列值长度较长的索引列,我们建议使用前缀索引.

(5) 降低索引条目,一方面不要创建没用索引,不常使用的索引清理,percona toolkit

(6) 索引维护要避开业务繁忙期

十、不走索引的情况

1、没有查询条件,或者查询条件没有建立索引

2、查询结果集是原表中的大部分数据,应该是25%以上

3、索引本身失效,统计数据不真实

4、查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等)

5、隐式转换导致索引失效.这一点应当引起重视,也是开发中经常会犯的错误.

6、<> ,not in 不走索引

7、 like "%_" 百分号在最前面不走

8、单独引用联合索引里非第一位置的索引列.作为条件查询时不走索引.

十一、压力测试

1、模拟数据库数据

vim slap.sh
    ...

# 执行脚本:
sh slap.sh

2、检查数据可用性

mysql -uroot -p123
select count(*) from oldboy.t1;

3、优化前进行压力测试

mysqlslap --defaults-file=/etc/my.cnf  --concurrency=100 --iterations=1 --create-schema=‘oldboy‘ --query="select * from oldboy.t1 where stuname=‘alexsb_100‘" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose

4、创建索引再测试

mysql> alter table t1 add index idx_name(stuname);

# 重复第三步,进行压力测试

原文地址:https://www.cnblogs.com/linagcheng/p/10298046.html

时间: 2024-08-01 22:33:12

数据库优化(二)—— MySQL索引优化的相关文章

Mysql 索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别. MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵

mySql索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别.MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵活

【转载】MySQL索引优化

MySQL索引优化 原文链接 MySQL官方对索引的定义:索引是帮助MySQL高效获取数据的数据结构.索引是在存储引擎中实现的,所以每种存储引擎中的索引都不一样.如MYISAM和InnoDB存储引擎只支持BTree索引:MEMORY和HEAP储存引擎可以支持HASH和BTREE索引. 这里仅针对常用的InnoDB存储引擎所支持的BTree索引进行介绍: 一.索引类型 先创建一个新表,用于演示索引类型 CREATE TABLE index_table ( id BIGINT NOT NULL au

mysql索引优化

mysql 索引优化 >mysql一次查询只能使用一个索引.如果要对多个字段使用索引,建立复合索引. >越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间,处理起来更快. >简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂.在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间:以及用整型数据类型存储IP地址. >尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL.在MySQL中,含有空

MySQL索引优化-from 高性能MYSQL

Btree: 1. 尽量使用覆盖索引, 即三星索引 2. 多列索引如果带范围的话, 后续列不会作为筛选条件 3. 多列索引应选择过滤性更好的充当前缀索引 4. 尽量按主键顺序插入, 减少页分裂, 采用自增ID在高并发情况下, 可能造成明显征用, 或者更改innodb_autoinc_lock_mode配置. Hash: 1.只有精确匹配所有列的查询才有效, 对于每行数据, 引擎都会对所有索引列计算hash码 2. 只有memory才可以支持hash索引, innodb支持自适应hash索引, 但

MySQL索引优化步骤总结

在项目使用mysql过程中,随着系统的运行,发现一些慢查询,在这里总结一下mysql索引优化步骤 1.开发过程优化 开发过程中对业务表中查询sql分析sql执行计划(尤其是业务流水表),主要是查看sql执行计划,对sql进行优化. explain执行计划关键属性 select_type,possible_keys,key,rows (1) select_type 访问类型 system>const > eq_ref > ref > fulltext > ref_or_null

重新学习MySQL数据库4:Mysql索引实现原理

重新学习Mysql数据库4:Mysql索引实现原理 MySQL索引类型 (https://www.cnblogs.com/luyucheng/p/6289714.html) 一.简介 MySQL目前主要有以下几种索引类型: 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引 二.语句 CREATE TABLE table_name[col_name data type][unique|fulltext][index|key][index_name](col_name[lengt

MySQL性能优化(二)索引优化

一.选择合适的列建立索引 1.在where从句,group by从句,order by从句,on从句中出现的列(select)2.索引字段越小越好(表每页数据才会更多,IO效率会更高)3.离散度大的列放到联合索引的前面select * from payment where staff_id=2 and customer_id=584;index(staff_id,customer_id)好?还是index(customer_id,staff_id)好?由于customer_id的离散度更大(重复

mysql 索引优化的要点(系列一)

背景:sql 优化对数据来说是什么非常重要,sql的索引优化更重中之重,有的人认为索引优化就是简单加一个索引,其实这种想法是错的,索引是涉及到很多知识点,并非大家想得这么简单,废话不多说,马上开车! 一,头盘: SQL语句的五大要素:1,获得结果集所需访问的查询条件2,定义结果集所需的查询条件3,结果集的大小4,获得结果集所涉及的表的数量5,多少用户同时修改这些数据 二,主菜:索引的一些特性和优化建议 1,经常变的索引列放在最后,这样会降低变更成本2,索引字段的顺序非常重要,如果排序前有范围查询