Mysql 学习
分页查询优化
首先筛选条件加索引,这个不用多说了。
一般的分页查询如下:
SELECT *
FROM employees
ORDER BY id
LIMIT 10 OFFSET 9990;
- 数据库需要先扫描前 9990 条数据,然后再返回接下来的 10 条数据。
- 这种操作的开销非常大。
优化方法:
采用游标查询,通过记录上一次分页查询的最后一次的id,来筛掉之前查过的数据,一般这个值都是前端记录然后查询的时候传给后端。
SELECT *
FROM employees
WHERE id > lastId
ORDER BY id
LIMIT 10;
Mysql的索引结构
b+树,
- 主键索引的叶子节点存储完整的数据行,其他二级索引叶子节点存储的是主键
- 叶子节点之间通过双向链表连接,叶子节点内部的数据以有序数组的结构存放
Mysql建索引的建议
- 不参与条件筛选的列不建索引
- 区分度不高的列不建索引,比如性别
- 与第一条相似,参与where条件筛选与分组group by和排序order by 的列建索引
- 频繁更新的列不建索引,应为会经常改变索引b+树的结构
Mysql的锁
按锁的粒度分 表级锁(主要用于Myisam),行级锁
按锁的类型分,共享锁和排他锁,
在innode db中的行锁类型分为记录锁 、间隙锁和临键锁
Mysql 语句的执行顺序
- from
- where
- group by
- having
- select
- distinct
- order by
- limit/offset
Mysql 的常见的运算函数
1. 数学函数
用于数值计算和操作。
| 函数名 | 描述 | 示例 |
|---|---|---|
ABS(x) |
返回 x 的绝对值 |
ABS(-10) → 10 |
CEIL(x) |
返回大于或等于 x 的最小整数 |
CEIL(3.14) → 4 |
FLOOR(x) |
返回小于或等于 x 的最大整数 |
FLOOR(3.14) → 3 |
ROUND(x, d) |
将 x 四舍五入到 d 位小数 |
ROUND(3.14159, 2) → 3.14 |
TRUNCATE(x, d) |
将 x 截断到 d 位小数 |
TRUNCATE(3.14159, 2) → 3.14 |
MOD(x, y) |
返回 x 除以 y 的余数 |
MOD(10, 3) → 1 |
POW(x, y) |
返回 x 的 y 次方 |
POW(2, 3) → 8 |
SQRT(x) |
返回 x 的平方根 |
SQRT(16) → 4 |
RAND() |
返回 0 到 1 之间的随机数 | RAND() → 0.123456 |
2. 字符串函数
用于字符串操作和处理。
| 函数名 | 描述 | 示例 |
|---|---|---|
CONCAT(s1, s2, ...) |
连接多个字符串 | CONCAT('Hello', ' ', 'World') → 'Hello World' |
SUBSTRING(s, start, length) |
从 s 中提取子字符串 |
SUBSTRING('Hello', 2, 3) → 'ell' |
LENGTH(s) |
返回字符串的长度 | LENGTH('Hello') → 5 |
UPPER(s) |
将字符串转换为大写 | UPPER('hello') → 'HELLO' |
LOWER(s) |
将字符串转换为小写 | LOWER('HELLO') → 'hello' |
TRIM(s) |
去除字符串两端的空格 | TRIM(' Hello ') → 'Hello' |
REPLACE(s, old, new) |
将字符串中的 old 替换为 new |
REPLACE('Hello', 'H', 'J') → 'Jello' |
REVERSE(s) |
反转字符串 | REVERSE('Hello') → 'olleH' |
LEFT(s, n) |
返回字符串左边的 n 个字符 |
LEFT('Hello', 2) → 'He' |
RIGHT(s, n) |
返回字符串右边的 n 个字符 |
RIGHT('Hello', 2) → 'lo' |
3. 日期和时间函数
用于处理日期和时间数据。
| 函数名 | 描述 | 示例 |
|---|---|---|
NOW() |
返回当前日期和时间 | NOW() → 2023-10-01 12:34:56 |
CURDATE() |
返回当前日期 | CURDATE() → 2023-10-01 |
CURTIME() |
返回当前时间 | CURTIME() → 12:34:56 |
DATE(date) |
提取日期部分 | DATE('2023-10-01 12:34:56') → '2023-10-01' |
TIME(date) |
提取时间部分 | TIME('2023-10-01 12:34:56') → '12:34:56' |
YEAR(date) |
提取年份 | YEAR('2023-10-01') → 2023 |
MONTH(date) |
提取月份 | MONTH('2023-10-01') → 10 |
DAY(date) |
提取日 | DAY('2023-10-01') → 1 |
DATEDIFF(date1, date2) |
返回两个日期之间的天数差 | DATEDIFF('2023-10-01', '2023-09-01') → 30 |
DATE_ADD(date, INTERVAL) |
在日期上添加时间间隔 | DATE_ADD('2023-10-01', INTERVAL 1 DAY) → '2023-10-02' |
DATE_SUB(date, INTERVAL) |
在日期上减去时间间隔 | DATE_SUB('2023-10-01', INTERVAL 1 DAY) → '2023-09-30' |
4. 聚合函数
用于对一组值进行计算并返回单个值。
| 函数名 | 描述 | 示例 |
|---|---|---|
COUNT() |
返回行数 | COUNT(*) → 总行数 |
SUM() |
返回数值列的总和 | SUM(price) → 所有价格的总和 |
AVG() |
返回数值列的平均值 | AVG(price) → 价格的平均值 |
MIN() |
返回最小值 | MIN(price) → 最低价格 |
MAX() |
返回最大值 | MAX(price) → 最高价格 |
GROUP_CONCAT() |
将分组的值连接成字符串 | GROUP_CONCAT(name) → 'Alice,Bob' |
5. 条件函数
用于条件判断和逻辑操作。
| 函数名 | 描述 | 示例 |
|---|---|---|
IF(expr, true_val, false_val) |
如果 expr 为真,返回 true_val,否则返回 false_val |
IF(1 > 0, 'Yes', 'No') → 'Yes' |
CASE |
多条件判断 | CASE WHEN score > 90 THEN 'A' WHEN score > 80 THEN 'B' ELSE 'C' END |
COALESCE(val1, val2, ...) |
返回第一个非空值 | COALESCE(NULL, 'Default') → 'Default' |
NULLIF(val1, val2) |
如果 val1 等于 val2,返回 NULL |
NULLIF(10, 10) → NULL |
6. 类型转换函数
用于数据类型转换。
| 函数名 | 描述 | 示例 |
|---|---|---|
CAST(expr AS type) |
将 expr 转换为指定类型 |
CAST('123' AS INT) → 123 |
CONVERT(expr, type) |
将 expr 转换为指定类型 |
CONVERT('123', SIGNED) → 123 |
7. 其他常用函数
| 函数名 | 描述 | 示例 |
|---|---|---|
IFNULL(val1, val2) |
如果 val1 为 NULL,返回 val2 |
IFNULL(NULL, 'Default') → 'Default' |
GREATEST(val1, val2, ...) |
返回最大值 | GREATEST(10, 20, 30) → 30 |
LEAST(val1, val2, ...) |
返回最小值 | LEAST(10, 20, 30) → 10 |

浙公网安备 33010602011771号