php优化mysql表_PHP 之Mysql优化

本文介绍SQL优化的方法,包括索引管理如普通索引、唯一索引等;查询缓存的使用及注意事项;分区策略如Key、Hash等;分表技术如水平分表、垂直分表;以及SQL语句优化和慢查询日志的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、建立索引

普通索引 index: 对关键字没有要求。

唯一索引 unique index: 要求关键字不能重复。同时增加唯一约束。

主键索引 primary key: 要求关键字不能重复,也不能为NULL。同时增加主键约束。

全文索引 fulltext key: 关键字的来源不是所有字段的数据,而是从字段中提取的特别关键词。

索引的管理:

建表时

90ed6151a1fd89c203d7eda35f092f18.png

更新表结构

5017d06b59a60082aa9b02b8057acfd9.png

1、前缀索引

建立前缀索引的语法:

alter table test add KEY (name(5));

name一定是字符类型(索引字段),5为长度

那好,如何确定取前面几个字符呢?显然,这个场景是一个观察的结果,也就是说,必须要有一定量的实际数据,我们才能分析出其规律,也就是说这个索引是在后期优化得来的,前期没必要建立。

计算不重复的概率:

select COUNT(DISTINCT name) / COUNT(*) as rate from test;

找出接近rate的一个n(试出最合理的n)

select COUNT(DISTINCT LEFT(name, 3)) / COUNT() as rate3 from test;

select COUNT(DISTINCT LEFT(name, 5)) / COUNT() as rate5 from test;

select COUNT(DISTINCT LEFT(name, 7)) / COUNT() as rate7 from test;

select COUNT(DISTINCT LEFT(name, 9)) / COUNT() as rate9 from test;

select COUNT(DISTINCT LEFT(name, 11)) / COUNT() as rate11 from test;

select COUNT(DISTINCT LEFT(name, 15)) / COUNT() as rate15 from test;

select COUNT(DISTINCT LEFT(name, 20)) / COUNT(*) as rate20 from test;

2、全文索引

该类型的索引特殊在:关键字的创建上。为了解决 like ‘%keyword%’这类查询的匹配问题。

9e5a4c23cb9caf5ddf04726663e9ef9f.png

查询 标题或者内容包含 database 关键字的记录。

形成的SQL如下:

Select * from articles where title like ‘%database%’ or body like ‘%database%’;

此时需要建立全文索引

df63b64d48525a38953084aac9c88686.png

直接使用上面的SQL:

需要使用特殊的全文索引匹配语法才可以生效:

Match() against();

c0516153f3f7a66b3854448e77636701.png

注意:mysql提供的全文索引不能对中文起作用,可以采用

Match() against() ,返回的关键字的匹配度(关键字与记录的关联程度)。

aadc353d836f336211e85cced0f4887e.png

3、Explain 执行计划

可以通过在select语句前使用 explain,来获取该查询语句的执行计划,而不是真正执行该语句。

b03d210255cb4264ad49ff2e37c577ce.png

二、查询缓存(query_cache)

查看缓存配置:

ec4e4535ae9533acbdda18e4c4611bc1.png

开启并设置大小:

5b94c2b0093f7942160f77e6e156f4e8.png

9d556fd103ea207c68df6ab56cf82450.png

注意事项:

1、严格保证SQL一致,区分大小写等。

2、 如果查询时包含动态数据,则不能被缓存。

3、一旦开启查询缓存,MySQL会将所有可以被缓存的select语句都缓存。如果存在不想使用缓存的SQL执行,则可以使用 SQL_NO_CACHE语法提示达到目的。

三、分区

1、分区语法

Create table table_name (

定义

)

Partition by 分区算法 (参数) 分区选项。

注意:分区与存储引擎无关,是MySQL逻辑层完成的。

通过变量查看当前mysql是否支持分区:

173acb9e4625fbc30baebaa65f0808a3.png

分区算法:

MySQL提供4种

取余:Key,hash

条件:List,range

提示,参与分区的参数字段需要为主键的一部分。

key - 按照某个字段进行取余

6ea349588afae7a605f63a80bbcbdfbf.png

Hash - 按照某个表达式的值进行取余

2a7228bef2fe81fd8c5cf4b708c0cd3a.png

注意:Key,hash都是取余算法,要求分区参数,返回的数据必须为整数。

List - 需要指定的每个分区数据的存储条件

e7d153dc71f481767ac3a620e7368699.png

Range - 条件依赖的数据是一个条件表达式

47ee93e77639cee7d9ecebb190b00919.png

2、管理分区语法

取余:key和hash

增加分区数量:

3b82e68d5eec806e2cbbc9b9c443e274.png

减少分区数量:

04891239b2cc18fb5e3f0a2866545c50.png

采用取余算法的分区数量的修改,不会导致已有分区数据的丢失,需要重新分配数据到新大地分区。

条件:List和Range

添加分区:

9ac1aef980de6694a8154bd63ca28881.png

删除分区:

8d9018374a27411c4cc6ee3fb068f5b6.png

注意:删除条件算法的分区,导致分区数据丢失。

四、分表

1、水平分表案例

创建结构相同的N个表:

5b8331e3ba34c25d2e8caa3ad887cdce.png

再创建用于管理学生ID的表:

946779c207bb4e271ddf0dcaae491a96.png

PHP客户端逻辑:

59cccd452e37108b46190d899469dab2.png

2、垂直分表

表中存在多个字段。

常用字段 - 非常有字段

主要目的,减少每条记录的长度。

例如学生表可以分成:

基础表和额外表,两张表中记录为1:1的关系。

案例:

基础信息表

Student_base

Id name age

额外信息表

Student_extra

Id 籍贯 政治面貌

五、架构层面

2876cd14b98f535bbb80d8d2a7274618.png

1caf82d62c509079ab9ddb172ee3b58f.png

六、SQL语句

将复杂的SQL拆分多次执行。

案例:

商品,分类:

Select * from category;分类列表

Select cat_id, count(*) from goods group by goods;分类对应的商品数量。

分页

Limit offset, size;

Size = 10;

Page

offset

5

40, 10

50

490, 10

5000

4990, 10

500000

499990, 10

Limit 的使用,会大大提升无效数据的检索(被跳过)。

应该使用条件等过滤方式,将检索到的数据尽可能精确定位到需要的数据上。

例如分页:

Limit size;

七、慢查询日志

查看慢查询日志:

cffc663367a1139f65ab04e913ea85de.png

开启日志:

384bc0ad28892990f230814e0b8ee3a7.png

日志信息如下:

e64f9f6243300dc74d8f4839b50a484c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值