MySQL提升大量数据查询效率的优化神器


Posted in MySQL onJuly 07, 2022

前言

在应用的的开发过程中,由于初期数据量小,开发人员写 SQL 语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多 SQL 语句开始逐渐显露出性能问题,对生产的影响也越来越大,此时这些有问题的 SQL 语句就成为整个系统性能的瓶颈,因此我们必须要对它们进行优化.

为什么这么说呢?因为在MySQL查询语句中,语法比较的通用吗,要想得到一个数据集可以使用不同的查询语句!

例如我们需要查询一个数据表有多少行数据集?

1、暴力搜索

select count(*) from data;

这样虽然也可以达到效果,但是用 "SELECT * " 数据库需要解析更多的对象、字段、权限、属性等相关内容,在 SQL 语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担。

增大网络开销,* 有时会误带上如log、IconMD5之类的无用且大文本字段,数据传输size会几何增长。特别是MySQL和应用程序不在同一台机器,这种开销非常明显。

2、限定字段查询

select count(id) from data;

这里的id是一个递增的序列,查询效果确实有所提升。

MySQL的优化方式有很多,大致我们可以从以下几点来优化MySQL:

  • 从设计上优化
  • 从查询上优化
  • 从索引上优化
  • 从存储上优化

查看SQL执行频率

MySQL 客户端连接成功后,通过 show [session|global] status 命令可以查看服务器状态信息。通过查看状态信息可以查看对当前数据库的主要操作类型。

--下面的命令显示了当前 session 中所有统计参数的值
show session status like 'Com_______'; -- 查看当前会话统计结果
show global status like 'Com_______'; -- 查看自数据库上次启动至今统计结果
show status like 'Innodb_rows_%'; -- 查看针对Innodb引擎的统计结果

MySQL提升大量数据查询效率的优化神器

 定位低效率执行SQL

可以通过以下两种方式定位执行效率较低的 SQL 语句。

慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句。

show processlist:该命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。

-- 查看慢日志配置信息
show variables like '%slow_query_log%';
-- 开启慢日志查询
set global slow_query_log=1;
-- 查看慢日志记录SQL的最低阈值时间
show variables like 'long_query_time%';
-- 修改慢日志记录SQL的最低阈值时间
set global long_query_time=4;
 
show processlist;

MySQL提升大量数据查询效率的优化神器

  • 1) id列,用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看
  • 2) user列,显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句
  • 3) host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户
  • 4) db列,显示这个进程目前连接的是哪个数据库
  • 5) command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等
  • 6) time列,显示这个状态持续的时间,单位是秒
  • 7) state列,显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成
  • 8) info列,显示这个sql语句,是判断问题语句的一个重要依据

explain分析执行计划

通过以上步骤查询到效率低的 SQL 语句后,可以通过 EXPLAIN命令获取 MySQL如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。

-- 准备测试数据
create database mydb13_optimize;
use mydb13_optimize;

执行sql脚本sql_optimize.sql添加数据

explain select * from user where uid = 1;

MySQL提升大量数据查询效率的优化神器

MySQL提升大量数据查询效率的优化神器

 id 字段是 select查询的序列号,是一组数字,表示的是查询中执行select子句或者是操作表的顺序。id 情况有三种:

1、id 相同表示加载表的顺序是从上到下

explain select * from user u, user_role ur, role r where u.uid = ur.uid and ur.rid = r.rid ;

MySQL提升大量数据查询效率的优化神器

2、 id 不同id值越大,优先级越高,越先被执行。

explain select * from role where rid =
(select rid from user_role where uid = (select uid from user where uname = '张飞'))

MySQL提升大量数据查询效率的优化神器

3、 id 有相同,也有不同,同时存在。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行。

MySQL提升大量数据查询效率的优化神器

  表示 SELECT 的类型,常见的取值,如下表所示:

MySQL提升大量数据查询效率的优化神器

type 显示的是访问类型,是较为重要的一个指标,可取值为:  

MySQL提升大量数据查询效率的优化神器

结果从最到最坏以此:system > const > eq_ref > ref > range > index > ALL 

MySQL提升大量数据查询效率的优化神器

其他的额外的执行计划信息,在该列展示 。

MySQL提升大量数据查询效率的优化神器

 Mysql从5.0.37版本开始增加了对 show profiles 和 show profile 语句的支持。show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。

通过 have_profiling 参数,能够看到当前MySQL是否支持profile:

select @@have_profiling;
set profiling=1; -- 开启profiling 开关;

 通过profile,我们能够更清楚地了解SQL执行的过程。首先,我们可以执行一系列的操作

show databases;
use mydb13_optimize;
show tables;
select * from user where id < 2;
select count(*) from user;

执行完上述命令之后,再执行show profiles 指令, 来查看SQL语句执行的耗时:

show profiles;

MySQL提升大量数据查询效率的优化神器

 通过show  profile for  query  query_id 语句可以查看到该SQL执行过程中每个线程的状态和消耗的时间:

show profile for query 8;

MySQL提升大量数据查询效率的优化神器

 在获取到最消耗时间的线程状态后,MySQL支持进一步选择all、cpu、block io 、context switch、page faults等明细类型类查看MySQL在使用什么资源上耗费了过高的时间。例如,选择查看CPU的耗费时间  :

show profile cpu for query 133;

MySQL提升大量数据查询效率的优化神器

 在获取到最消耗时间的线程状态后,MySQL支持进一步选择all、cpu、block io 、context switch、page faults等明细类型类查看MySQL在使用什么资源上耗费了过高的时间。例如,选择查看CPU的耗费时间  :

MySQL提升大量数据查询效率的优化神器

trace分析优化器执行计划

MySQL5.6提供了对SQL的跟踪trace, 通过trace文件能够进一步了解为什么优化器选择A计划, 而不是选择B计划

MySQL提升大量数据查询效率的优化神器

 
SET optimizer_trace="enabled=on",end_markers_in_json=on;
set optimizer_trace_max_mem_size=1000000;

 执行SQL语句 :
 

select * from user where uid < 2;

最后, 检查information_schema.optimizer_trace就可以知道MySQL是如何执行SQL的 :

select * from information_schema.optimizer_trace\G;

MySQL提升大量数据查询效率的优化神器

使用索引优化

索引是数据库优化最常用也是最重要的手段之一, 通过索引通常可以帮助用户解决大多数的MySQL的性能优化问题。

create table `tb_seller` (
`sellerid` varchar (100),
`name` varchar (100),
`nickname` varchar (50),
`password` varchar (60),
`status` varchar (1),
`address` varchar (100),
`createtime` datetime,
primary key(`sellerid`)
);

 索引是数据库优化最常用也是最重要的手段之一, 通过索引通常可以帮助用户解决大多数的MySQL的性能优化问题。

insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('alibaba','阿里巴巴','阿里小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('baidu','百度科技有限公司','百度小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('huawei','华为科技有限公司','华为小店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itcast','传智播客教育科技有限公司','传智播客','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itheima','黑马程序员','黑马程序员','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('luoji','罗技科技有限公司','罗技小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('oppo','OPPO科技有限公司','OPPO官方旗舰店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('ourpalm','掌趣科技股份有限公司','掌趣小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('qiandu','千度科技','千度小店','e10adc3949ba59abbe56e057f20f883e','2','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('sina','新浪科技有限公司','新浪官方旗舰店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('xiaomi','小米科技','小米官方旗舰店','e10adc3949ba59abbe56e057f20f883e','1','西安市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('yijia','宜家家居','宜家家居旗舰店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
 
-- 创建组合索引
create index idx_seller_name_sta_addr on tb_seller(name,status,address);

该情况下,索引生效,执行效率高。

explain select * from tb_seller where name='小米科技' and status='1' and address='北京市';

避免索引失效应用-最左前缀法则

-- 最左前缀法则
-- 如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。
explain select * from tb_seller where name='小米科技'; -- 403

explain select * from tb_seller where name='小米科技' and status='1'; -- 410
explain select * from tb_seller where status='1' and name='小米科技'; -- 410
-- 违法最左前缀法则 , 索引失效:
explain select * from tb_seller where status='1'; -- nulll

-- 如果符合最左法则,但是出现跳跃某一列,只有最左列索引生效:
explain select * from tb_seller where name='小米科技' and address='北京市'; -- 403

索引失效应用-其他匹配原则

-- 范围查询右边的列,不能使用索引 。
explain select * from tb_seller where name='小米科技' and status >'1' and address='北京市';

-- 不要在索引列上进行运算操作, 索引将失效。
explain select * from tb_seller where substring(name,3,2)='科技'

-- 字符串不加单引号,造成索引失效。
explain select * from tb_seller where name='小米科技' and status = 1 ;

避免索引失效应用-其他匹配原则 :

-- 1、范围查询右边的列,不能使用索引 。
-- 根据前面的两个字段name , status 查询是走索引的, 但是最后一个条件address 没有用到索引。
explain select * from tb_seller where name='小米科技' and status >'1' and address='北京市';

-- 2、不要在索引列上进行运算操作, 索引将失效。
explain select * from tb_seller where substring(name,3,2)='科技'

-- 3、字符串不加单引号,造成索引失效。
explain select * from tb_seller where name='小米科技' and status = 1 ;

-- 4、尽量使用覆盖索引,避免select *
-- 需要从原表及磁盘上读取数据
explain select * from tb_seller where name='小米科技' and address='北京市'; -- 效率低

-- 从索引树中就可以查询到所有数据
explain select name from tb_seller where name='小米科技' and address='北京市'; -- 效率高
explain select name,status,address from tb_seller where name='小米科技' and address='北京市'; -- 效率高
-- 如果查询列,超出索引列,也会降低性能。
explain select name,status,address,password from tb_seller where name='小米科技' and address='北京市'; -- 效率低
 
-- 尽量使用覆盖索引,避免select *
-- 需要从原表及磁盘上读取数据
explain select * from tb_seller where name='小米科技' and address='北京市'; -- 效率低

-- 从索引树中就可以查询到所有数据
explain select name from tb_seller where name='小米科技' and address='北京市'; -- 效率高
explain select name,status,address from tb_seller where name='小米科技' and address='北京市'; -- 效率高
-- 如果查询列,超出索引列,也会降低性能。
explain select name,status,address,password from tb_seller where name='小米科技' and address='北京市'; -- 效率低

-- 用or分割开的条件, 那么涉及的索引都不会被用到。
explain select * from tb_seller where name='黑马程序员' or createtime = '2088-01-01 12:00:00';
explain select * from tb_seller where name='黑马程序员' or address = '西安市';
explain select * from tb_seller where name='黑马程序员' or status = '1';

-- 以%开头的Like模糊查询,索引失效。
explain select * from tb_seller where name like '科技%'; -- 用索引
explain select * from tb_seller where name like '%科技'; -- 不用索引
explain select * from tb_seller where name like '%科技%';-- 不用索引
-- 弥补不足,不用*,使用索引列
explain select name from tb_seller where name like '%科技%';
 
-- 1、如果MySQL评估使用索引比全表更慢,则不使用索引。
-- 这种情况是由数据本身的特点来决定的
create index index_address on tb_seller(address);
explain select * from tb_seller where address = '北京市'; -- 没有使用索引
explain select * from tb_seller where address = '西安市'; -- 没有使用索引
-- 2、is NULL , is NOT NULL 有时有效,有时索引失效。
create index index_address on tb_seller(nickname);
explain select * from tb_seller where nickname is NULL; -- 索引有效
explain select * from tb_seller where nickname is not NULL; -- 无效

SQL优化

create table `tb_user` (
`id` int(11) not null auto_increment,
`username` varchar(45) not null,
`password` varchar(96) not null,
`name` varchar(45) not null,
`birthday` datetime default null,
`sex` char(1) default null,
`email` varchar(45) default null,
`phone` varchar(45) default null,
`qq` varchar(32) default null,
`status` varchar(32) not null comment '用户状态',
`create_time` datetime not null,
`update_time` datetime default null,
primary key (`id`),
unique key `unique_user_username` (`username`)
);

当使用load 命令导入数据的时候,适当的设置可以提高导入的效率。对于 InnoDB 类型的表,有以下几种方式可以提高导入的效率:

大量插入数据

1) 主键顺序插入

因为InnoDB类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率。如果InnoDB表没有主键,那么系统会自动默认创建一个内部列作为主键,所以如果可以给表创建一个主键,将可以利用这点,来提高导入数据的效率。

MySQL提升大量数据查询效率的优化神器

 
-- 1、首先,检查一个全局系统变量 'local_infile' 的状态, 如果得到如下显示 Value=OFF,则说明这是不可用的
show global variables like 'local_infile';

-- 2、修改local_infile值为on,开启local_infile
set global local_infile=1;

-- 3、加载数据
/*
脚本文件介绍 :
sql1.log ----> 主键有序
sql2.log ----> 主键无序
*/
load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';

  2 )、关闭唯一性校验

在导入数据前执行 SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。

-- 关闭唯一性校验
SET UNIQUE_CHECKS=0;
truncate table tb_user;
load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';
SET UNIQUE_CHECKS=1;

优化insert语句

-- 数据有序插入
insert into tb_test values(4,'Tim');
insert into tb_test values(1,'Tom');
insert into tb_test values(3,'Jerry');
insert into tb_test values(5,'Rose');
insert into tb_test values(2,'Cat');
-- 优化后
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
insert into tb_test values(4,'Tim');
insert into tb_test values(5,'Rose');

优化order by语句

CREATE TABLE `emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` int(3) NOT NULL,
`salary` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
insert into `emp` (`id`, `name`, `age`, `salary`) values('1','Tom','25','2300');
insert into `emp` (`id`, `name`, `age`, `salary`) values('2','Jerry','30','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('3','Luci','25','2800');
insert into `emp` (`id`, `name`, `age`, `salary`) values('4','Jay','36','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('5','Tom2','21','2200');
insert into `emp` (`id`, `name`, `age`, `salary`) values('6','Jerry2','31','3300');
insert into `emp` (`id`, `name`, `age`, `salary`) values('7','Luci2','26','2700');
insert into `emp` (`id`, `name`, `age`, `salary`) values('8','Jay2','33','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('9','Tom3','23','2400');
insert into `emp` (`id`, `name`, `age`, `salary`) values('10','Jerry3','32','3100');
insert into `emp` (`id`, `name`, `age`, `salary`) values('11','Luci3','26','2900');
insert into `emp` (`id`, `name`, `age`, `salary`) values('12','Jay3','37','4500');
create index idx_emp_age_salary on emp(age,salary);

2、两种排序方式

第一种是通过对返回数据进行排序,也就是通常说的 filesort 排序,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。

第二种通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要额外排序,操作效率高。

3、Filesort 的优化

通过创建合适的索引,能够减少 Filesort 的出现,但是在某些情况下,条件限制不能让Filesort消失,那就需要加快 Filesort的排序操作。

对于Filesort , MySQL 有两种排序算法:

  • 1) 两次扫描算法 :MySQL4.1 之前,使用该方式排序。首先根据条件取出排序字段和行指针信息,然后在排序区 sort buffer 中排序,如果sort buffer不够,则在临时表 temporary table 中存储排序结果。完成排序之后,再根据行指针回表读取记录,该操作可能会导致大量随机I/O操作。
  • 2)一次扫描算法:一次性取出满足条件的所有字段,然后在排序区 sort  buffer 中排序后直接输出结果集。排序时内存开销较大,但是排序效率比两次扫描算法要高。

MySQL 通过比较系统变量 max_length_for_sort_data 的大小和Query语句取出的字段总大小, 来判定是否那种排序算法,如果max_length_for_sort_data 更大,那么使用第二种优化之后的算法;否则使用第一种。

可以适当提高 sort_buffer_size  和 max_length_for_sort_data  系统变量,来增大排序区的大小,提高排序的效率。

优化group by

于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引。

如果查询包含 group by 但是用户想要避免排序结果的消耗, 则可以执行order by null 禁止排序。

如下 :

drop index idx_emp_age_salary on emp;
explain select age,count(*) from emp group by age;
explain select age,count(*) from emp group by age order by null;
create index idx_emp_age_salary on emp(age,salary);

子查询优化

使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询是可以被更高效的连接(JOIN)替代。
 

explain select * from user where uid in (select uid from user_role );

MySQL提升大量数据查询效率的优化神器

 
explain select * from user u , user_role ur where u.uid = ur.uid;
system>const>eq_ref>ref>range>index>ALL

连接(Join)查询之所以更有效率一些 ,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。

limit优化

一般分页查询时,通过创建覆盖索引能够比较好地提高性能。一个常见又非常头疼的问题就是 limit 900000,10  ,此时需要MySQL排序前900010 记录,仅仅返回900000 - 900010 的记录,其他记录丢弃,查询排序的代价非常大 。

  • 1、在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。
  • 2、该方案适用于主键自增的表,可以把Limit 查询转换成某个位置的查询 。

到此这篇关于MySQL提升大量数据查询效率的优化神器的文章就介绍到这了,更多相关MySQL优化神器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

MySQL 相关文章推荐
教你用eclipse连接mysql数据库
Apr 22 MySQL
详解MySQL的半同步
Apr 22 MySQL
MySQL 常见存储引擎的优劣
Jun 02 MySQL
MySQL系列之一 MariaDB-server安装
Jul 02 MySQL
解决mysql的int型主键自增问题
Jul 15 MySQL
SQL基础查询和LINQ集成化查询
Jan 18 MySQL
一文简单了解MySQL前缀索引
Apr 03 MySQL
Windows下载并安装MySQL8.0.x 版本的完整教程
Apr 10 MySQL
Mysql查询时间区间日期列表,不会由于数据表数据影响
Apr 19 MySQL
Mysql中@和@@符号的详细使用指南
Jun 05 MySQL
数据设计之权限的实现
Aug 05 MySQL
MySQL使用IF语句及用case语句对条件并结果进行判断 
Sep 23 MySQL
mysql查看表结构的三种方法总结
Jul 07 #MySQL
MySQL中正则表达式(REGEXP)使用详解
MySQL实现字段分割一行转多行的示例代码
MySQL控制流函数(-if ,elseif,else,case...when)
Jul 07 #MySQL
mysql拆分字符串作为查询条件的示例代码
Jul 07 #MySQL
mysql全面解析json/数组
Jul 07 #MySQL
Mysql表数据比较大情况下修改添加字段的方法实例
You might like
PHP IDE PHPStorm配置支持友好Laravel代码提示方法
2015/05/12 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
2019/05/27 PHP
laravel实现登录时监听事件,添加登录用户的记录方法
2019/09/30 PHP
JavaScript进阶教程(第四课第一部分)
2007/04/05 Javascript
javascript XML数据显示为HTML一例
2008/12/23 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
javascript移出节点removeChild()使用介绍
2014/04/03 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
2015/09/27 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
AngularJS过滤器filter用法总结
2016/12/13 Javascript
AngularJS 表单验证手机号的实例(非必填)
2017/11/12 Javascript
详解vue文件中使用echarts.js的两种方式
2018/10/18 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
微信小程序swiper左右扩展各显示一半代码实例
2019/12/05 Javascript
vue通过过滤器实现数据格式化
2020/07/20 Javascript
vue.js watch经常失效的场景与解决方案
2021/01/07 Vue.js
[01:01:42]Secret vs Optic Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
跟老齐学Python之编写类之一创建实例
2014/10/11 Python
python中lambda与def用法对比实例分析
2015/04/30 Python
Python中内置数据类型list,tuple,dict,set的区别和用法
2015/12/14 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
使用python实现滑动验证码功能
2019/08/05 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
2019/08/22 Python
Python常用模块sys,os,time,random功能与用法实例分析
2020/01/07 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
Python try except else使用详解
2021/01/12 Python
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
服装厂厂长岗位职责
2013/12/27 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
保送生自荐信范文
2015/03/26 职场文书
2016入党积极分子心得体会
2016/01/06 职场文书
SQLServer2008提示评估期已过解决方案
2021/04/12 SQL Server
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
Python 数据可视化之Bokeh详解
2021/11/02 Python