一、前言
在写sql语句的时候常常会有很多疑问,那就是当单表的数据量很大的时候,查询性能怎么样,以及索引对数据查询的影响,今天用navicat批量造了很多重复数据来对mysq在数据量大的时候查询的性能的测试。
1 、使用navicat批量插入数据
函数--->新建函数-->填写名,选择函数,点击完成
填写函数
javascript
CREATE DEFINER=`root`@`%` PROCEDURE `userDataInsert`()
BEGIN
# 设置循环变量
DECLARE i INT DEFAULT 0;
WHILE i<=100000 DO
INSERT INTO sup_check(advertiser_id,check_time,record_types_id,dept_id) VALUES(20,'2024-04-09',1,203);
SET i = i + 1;
END WHILE;
END
保存后点击运行即可,此处会执行时间较长,主要看你的主机性能,磁盘的读写速度等,最好在自己的本地虚拟机中去跑,节省时间。
2、编写sql测试
此sql就是单表的查询(嵌套子查询),根据年份然后按照年月去对数据进行一个分组,问gpt的时候,gpt说使用函数的时候进行的是全表的扫描,不走索引,此时很慌,很想测试一下,走索引和不走索引到底有什么区别
sql
SELECT year(check_time) as year ,month(check_time) as month ,COUNT(*) as checkNum
FROM sup_check
WHERE
(dept_id = 100 OR dept_id IN (SELECT t.dept_id FROM sys_dept t WHERE FIND_IN_SET(100,ancestors)))
AND year(check_time) = 2024
GROUP BY year,month
ORDER BY year,month;
3、索引相关
- 单列索引
sql
CREATE INDEX idx_check_time
ON sup_check (check_time);
- 复合索引
sql
CREATE INDEX idx_column1_column2 ON sup_check (check_time, record_type_id);
- 唯一索引
sql
CREATE UNIQUE INDEX uidx_column_name ON table_name (column_name);
- 全文索引
sql
CREATE FULLTEXT INDEX ftx_column_name ON table_name (column_name);
- 使用表名 ,在某些情况下,你可能还想在索引名称中包含表名,尤其是在大型数据库中,这有助于避免索引名称冲突:
sql
CREATE INDEX idx_table_name_column_name ON table_name (column_name);
- 注意事项
避免使用特殊字符:不要在索引名称中使用特殊字符,如 !, @, #, $, %, ^, &, *, (, ), -, +, =, {, }, [, ], |, , ;, :, ', ", , <, >, /, ?`。
长度限制:MySQL索引名称的最大长度是64个字符 - 查看索引
这将返回以下列:
Table:表名
Non_unique:如果索引不能包含重复值,则为0;如果可以,则为1。
Key_name:索引的名称。
Seq_in_index:索引中的列序列号。
Column_name:列名。
Collation:列如何排序,如果是定序的,则显示排序顺序;如果是未排序的,则显示NULL。
Cardinality:索引中唯一值的估计数量。
Sub_part:如果列只是部分索引,则为索引的字符数。如果是整个列被索引,则为NULL。
Packed:指示关键字如何被压缩,如果没有被压缩,则为NULL。
Null:如果列含有NULL,则显示YES。
Index_type:索引类型,如BTREE、FULLTEXT、HASH等。
Comment:索引的备注信息。
sql
SHOW INDEX FROM table_name;
4、查询测试
建立完索引之后,我发现当查询出的数据量比较大的时候,查询指定数据的速度确实快了,但是当所查询出的字段多或者数据条数多的时候还是会耗费很长时间,那解决办法就是分页,一下查询出这么多条数据肯定慢,分页的话就特别快了。
sql
SELECT year(check_time) as year ,month(check_time) as month ,COUNT(*) as checkNum
FROM sup_check
WHERE
(dept_id = 100 OR dept_id IN (SELECT t.dept_id FROM sys_dept t WHERE FIND_IN_SET(100,ancestors)))
AND year(check_time) = 2024
GROUP BY year,month
ORDER BY year,month;
LIMIT 20 OFFSET 0;
5、提升sql的办法
优化sql,经常查询的字段使用索引,查询出需要使用的字段,分页查询
6、探讨分页查询的基本实现原理
首先使用count(*) 查询出数据总条数,此查询是经过mysql优化过的,速度比较快,或者你去count(索引列)然后就是根据每页的数据大小计算出总的页数(int totalPages = (totalRecords + pageSize - 1) / pageSize;),然后就是执行分页查询,查询指定页的数据