MySQL到底怎么优化?

Mysql的优化

数据库的性能取决于数据库级别的多个因素,比如表的设计、查询语句和数据库配置设置。这些软件结构导致硬件级别的 CPU 和 I/O 操作,必须减少CPU 和IO的使用才可以尽可能提高效率;

在数据库级别进行优化----

1,考虑表结构是否合理?----范式三原则
数据类型是否合适
2,是否设置了正确的索引?----索引重复字段最好不能有

3,每个表的存储引擎是否使用得当?(特别是,选择事务性存储引擎(如innodb)或非事务性存储引擎(如mysiam)对于性能和可伸缩性可能非常重要),

4,是否使用适当的锁定策略----表锁/行锁以便数据库可以并发操作;

5,用于缓存的所有内存区域大小是否合适?

这个可以调整mysql中缓存区的大小(bufferpoolmoren 64M),但又不能过大;

硬件级别的优化---->>

1,磁盘,磁盘查找数据需要一段时间,通常在10ms左右,因此理论上每秒会进行100次搜索,优化寻道时间是将数据分发到多个磁盘上;

或者可以更换高性能磁盘可以减少磁盘寻道时间比如使用固态硬盘;
2,cpu速度,更换为高性能cpu也可以加快处理速度;
3,内存带宽,当 CPU 需要的数据超过 CPU 缓存所能容纳的数据时,主内存带宽将成为瓶颈;

硬件级别的暂不在本次讨论范围

优化sql语句

1,查询语句是经常用的sql语句,优化查询的主要注意事项:

  • 要使慢查询更快----->>检查是否可以添加索引,为子句中的列设置索引;
    索引并不是越多越好,要考虑索引也占用磁盘空间;
  • 对于使用联结和外键等引用不同的表的查询,可以使用explain语句来确定用到了哪些索引;
  • 隔离和优化查询的任何部分
  • 尽可能减少全表扫描的次数,尤其是对于大型表
  • 可以通过定期分析表使得表系统的统计信息保持最新,优化sql的执行计划(select等)
  • 如果性能问题不能通过某个基本准则轻松解决,可使用 EXPLAIN 分析sql语句并调整索引、子句、联接子句等来调查特定查询的内部详细信息。
  • 调整MySQL用于缓存的内存区域的大小和属性。通过有效使用缓冲池、密钥缓存和 MySQL 查询缓存,重复查询的运行速度更快,因为结果会在第二次和后续时间从内存中检索。

Mysql优化细节

平时读数据的频率一般高于写数据,所以第一个应该考虑优化select语句;

数据表的设计:
数据类型的优化---->>>

1,数据类型占用更小的通常更好(因为一次能读取的数据量更多,这意味着在读取相同数据量的时候通常需要更少的CPU处理周期;
比如使用mysql中的日期数据类型而不是用字符串来存储日期;
用整型存储ip而不是字符串,(mysql中有一个函数可以将IP转换为整型 INET_ATON())
2,简单就好,尽量避免使用null
3,尽量避免使用null,在mysql中nul=null 的结果是null,但是有时候会出现填写信息时用户没有填写,此时我们可以指定数据为’’ 空字符串来代替null

在这里插入图片描述
4,合理设置主键
5,合理使用范式与反范式(根据实际情况来,可以适当有数据冗余)
6,字符集的选择
7,存储引擎的选择
8

优化select语句

1,解决慢查询的问题
首先是查看慢查询日志,找到慢查询产生的原因;

一般慢查询的优化需要从 索引入手------尝试给需要的字段添加索引;
对于使用联接和外键等功能引用不同表的查询,索引尤其重要。

2,将常用的数据缓存下来;

调整MySQL用于缓存的内存区域的大小和属性。通过有效使用缓冲池、密钥缓存和 MySQL 查询缓存,重复查询的运行速度更快,

3,减少全表扫描的次数;

尽量使用触发cont ,index等的查询,避免回表查询;

4,定期使用analyze table语句保持统计信息保持最新;

where条款优化

删除不必要的括号:

((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)

1,索引合并优化

索引合并访问方法检索具有多个范围扫描的行,并将其结果合并为一个。此访问方法仅合并来自单个表的索引扫描,而不合并跨多个表的扫描。合并可以生成其基础扫描的并集、交集或交集并集。

我们先看一张表----->>

mysql> select * from test ;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  2 | 张三2    | NULL |
|  4 | 张三4    | NULL |
|  6 | 李四     | NULL |
|  7 | 小七     | NULL |
|  8 | 王五     | NULL |
| 10 | 李四10   | NULL |
| 13 |13     | NULL |
| 18 | 王五18   | NULL |
+----+----------+------+
8 rows in set (0.00 sec)
#第一张表,有主键和索引name;
mysql> show create table test \G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int NOT NULL,
  `name` varchar(8) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `nameindex` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)

# 另一张表 只有主键
mysql> show create table test3 \G
*************************** 1. row ***************************
       Table: test3
Create Table: CREATE TABLE `test3` (
  `id` int NOT NULL,
  `name` varchar(8) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.01 sec)

接下来我们查询 id 小于10 和 name 为小七 的数据,如何才能够条查询效率??

第一张表----->>

mysql> explain select * from test where  id <10 and name="小七" \
G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: NULL
         type: index_merge
possible_keys: PRIMARY,nameindex
          key: nameindex,PRIMARY
      key_len: 39,4
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using intersect(nameindex,PRIMARY); Using where
1 row in set, 1 warning (0.00 sec)

在这里插入图片描述
官网给出的案例—>>

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name
  WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

SELECT * FROM t1, t2
  WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
  AND t2.key1 = t1.some_col;

SELECT * FROM t1, t2
  WHERE t1.key1 = 1
  AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMartain

祝:生活蒸蒸日上!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值