一步两步是魔鬼的步伐

Duan1v's Blog

wsl2使用主机代理之panda vpn

网上好多都是使用clash的的教程,设置vpn部分,panda点个✔就行

https://static.duan1v.top/images/dFSM1zBm72XCeag.png

配置一个开启代理的sh脚本:proxy.sh(来源找不到了)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/sh
hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
wslip=$(hostname -I | awk '{print $1}')
port=41091

PROXY_HTTP="http://${hostip}:${port}"

set_proxy(){
        export http_proxy="${PROXY_HTTP}"
        export HTTP_PROXY="${PROXY_HTTP}"

        export https_proxy="${PROXY_HTTP}"
        export HTTPS_proxy="${PROXY_HTTP}"
        echo "http proxy success!"
}

unset_proxy(){
        unset http_proxy
        unset HTTP_PROXY
        unset https_proxy
        unset HTTPS_PROXY
}

test_setting(){
        echo "Host ip:" ${hostip}
        echo "WSL ip:" ${wslip}
        echo "Current proxy:" $https_proxy
}

if [ "$1" = "set" ]
then
        set_proxy

elif [ "$1" = "unset" ]
then
        unset_proxy

elif [ "$1" = "test" ]
then
        test_setting
else
        echo "Unsupported arguments."
fi

开启代理

1
-> % source ~/proxy.sh set

检测是否成功

1
w3m google.com

出现下图则成功

https://static.duan1v.top/images/egEB9u3FsILlz1k.png

附 wsl 使用代理:

1
vim ~/.zshrc

追加下面代码

1
2
3
4
5
6
7
8
startProxy(){
        export https_proxy="http://127.0.0.1:41091";
        export http_proxy="http://127.0.0.1:41091";
}
stopProxy(){
        unset https_proxy;
        unset http_proxy;
}
1
2
3
source ~/.zshrc
# 开启代理
startProxy

附ping端口

1
2
3
4
sudo apt install tcptraceroute
sudo wget http://www.vdberg.org/~richard/tcpping -O /usr/bin/tcping
sudo chmod +x /usr/bin/tcping
tcping 目标IP 目标端口

MySQL学习笔记:索引失效

EXPLAIN中的type为range,而且rows过大时:

https://static.duan1v.top/images/fnPZRGhOQXNVeCx.png
MySQL学习笔记:索引失效
  • 查询临界值示例:
https://static.duan1v.top/images/gA9Bo4uTJKWNHVR.png
MySQL学习笔记:索引失效

一般情况:

以下参考:索引失效的情况(很棒的一篇文章,不过有些不准确,比如:使用 >= 不会失效,此处做个总结记录)

WHERE子句中

  • 未遵循最左原则
  • 在索引列上计算,使用函数
  • 在索引列上自动(如:`phone`=18172874277,`phone`是字符串型,所以等号后面的值应加引号),手动转换类型
  • 某列使用'>','<',右侧的索引列(按照组合索引字段顺序)
  • LIKE以通配符开头
  • 组合索引列之间使用OR

GROUP BY子句中(WHERE条件的索引是走的,之后的GROUP BY或者ORDER BY的索引是不走的)

不走索引的标准可以观察执行计划中的Extra: GROUP BY将使用额外的文件排序,以及产生临时表

  • 使用组合索引,须遵守最左原则(须按照索引顺序),WHERE子句中的索引字段是等值查询时,可以在GROUP BY子句中省略;
https://static.duan1v.top/images/LwYiUt9D7CJfanO.png
MySQL学习笔记:索引失效
https://static.duan1v.top/images/Rnzih58LpGmEbeS.png
MySQL学习笔记:索引失效
  • 存在一个组合索引和一个单索引时,GROUP BY的索引字段在WHERE子句中都有,且WHERE子句中的组合索引是等值查询,且WHERE子句中的单索引是等值查询或者执行计划中的key是单索引时,是用到索引的
https://static.duan1v.top/images/z4nIEPBYRivt9ks.png
MySQL学习笔记:索引失效
https://static.duan1v.top/images/gmuWPfkLtFHwDKb.png
MySQL学习笔记:索引失效

ORDER BY子句中,

不走索引的标准可以观察执行计划中的Extra: ORDER BY将使用额外的文件排序

  • 不使用WHERE子句时
https://static.duan1v.top/images/CXgj8Hv4cJoeySz.png
MySQL学习笔记:索引失效
  • 使用组合索引,须遵守最左原则(须按照索引顺序),且WHERE子句中有效的组合索引;WHERE子句中的有效索引字段是等值查询时,可以在ORDER BY子句中省略;
https://static.duan1v.top/images/VNpLDdQxzmtw2UW.png
MySQL学习笔记:索引失效
  • 存在多个单索引,或存在非索引字段时
https://static.duan1v.top/images/g4ZtmLA56KxSRCb.png
MySQL学习笔记:索引失效
  • 存在一个组合索引和一个单索引时,当表中只有一个组合索引,ORDER BY的索引字段在WHERE子句中都有,且WHERE子句中的组合索引是等值查询,且WHERE子句中的单索引是等值查询或者执行计划中的key是单索引时,是用到索引的
https://static.duan1v.top/images/sJZhQfiam5uDtFc.png
MySQL学习笔记:索引失效

注意:

  • 使用IN时,只有一个值时,相当于'=',有多个值时,索引也是有效的
https://static.duan1v.top/images/U9ouwYeEWIMHstP.png
MySQL学习笔记:索引失效
  • 索引列各自使用OR时,相当于IN
https://static.duan1v.top/images/N94UEZYsecyd25n.png
MySQL学习笔记:索引失效
  • LIKE以通配符结尾时,索引有效
https://static.duan1v.top/images/1lqGQ6FUvaNtIeW.png
MySQL学习笔记:索引失效
  • 使用'<=',索引有效
https://static.duan1v.top/images/uoQsRE8d3Sft1Kk.png
MySQL学习笔记:索引失效
  • 上述情况,EXPLAIN中的type为range,在rows过大时,索引均会失效。

MySQL学习笔记:组合索引-索引下推

索引下推

官网地址:Index Condition Pushdown Optimization

个人理解:

  • 开启ICP后,在查询索引时,会先检查无效索引(未走上的索引)是否满足条件,减少回表查询的次数,从而节省了查询 满足有效索引列条件下的 不符合无效索引列条件的所有行的查询时间。
https://static.duan1v.top/images/ugxmNVEaz8UcbJv.png
MySQL学习笔记:组合索引-索引下推
  • 很明显,索引没有走到uname
  • 在关闭ICP时,MySQL会回表查询`uname`!='5f686d59875ef'这个条件的完整行
  • 在开启ICP时,MySQL会先检查索引中的`uname`,然后在进行全表查询

实际查询,对比开启和关闭ICP时所用时间

1
2
3
4
5
SET profiling =  1; -- 开启profiling
SET query_cache_type =  0; -- 关闭query_cache
SET GLOBAL query_cache_size =  0;
SET optimizer_switch = 'index_condition_pushdown=off'; -- 关闭ICP
SET optimizer_switch = 'index_condition_pushdown=on'; -- 开启ICP
  • 先看看EXPLAIN,有效索引列:`dept_id`,无效索引列:`uname`
https://static.duan1v.top/images/Hbf6lrKLCOEsxGW.png
MySQL学习笔记:组合索引-索引下推
https://static.duan1v.top/images/wYDvVBx32I7LTbp.png
MySQL学习笔记:组合索引-索引下推
  • 再在开启关闭的情况下,分别执行三次SQL,查看查询时间;开启后比关闭后节省了大概75%的时间
https://static.duan1v.top/images/a3kwIErRglPn9UY.png
MySQL学习笔记:组合索引-索引下推

ICP注意事项:

  • EXPLAIN中的type须是range, ref, eq_ref, ref_or_null之一
  • 支持引擎:Myisam,InnoDB,允许分区
  • 对于InnoDB,不支持聚簇索引,只支持二级索引
  • 不支持虚拟列,子查询,存储函数,触发条件
  • 索引覆盖时,不用ICP

EXPLAIN中的type是range:

  • EXPLAIN中,type为range时,MySQL会根据符合有效索引列条件的计算rows(InnoDB是估值),如果过大,即使用索引不划算,将不走索引,从而不使用ICP
https://static.duan1v.top/images/VqpiY7aMRfk2HSU.png
MySQL学习笔记:组合索引-索引下推

索引覆盖

SELECT子句中查询的字段只有索引列,因此不需要根据二级索引查到的聚簇索引,再次回表查询完整行。

https://static.duan1v.top/images/JKR6epXSnsHN8WY.png
MySQL学习笔记:组合索引-索引下推

MySQL学习笔记:组合索引-最左原则

新建表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `uname` varchar(100) NOT NULL DEFAULT '' COMMENT '姓名',
  `nickname` varchar(255) NOT NULL DEFAULT '' COMMENT '昵称',
  `phone` char(11) NOT NULL DEFAULT '' COMMENT '电话',
  `emp_no` varchar(20) NOT NULL DEFAULT '' COMMENT '员工编号',
  `dept_id` int(4) NOT NULL DEFAULT '0' COMMENT '部门id',
  `pwd` varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
  `avt` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
  `addr` varchar(255) NOT NULL DEFAULT '' COMMENT '地址',
  PRIMARY KEY (`id`),
  KEY `index_user` (`dept_id`,`uname`,`phone`) USING BTREE,
  KEY `avt` (`avt`),
  KEY `emp_no` (`emp_no`),
  KEY `index_nickname` (`nickname`,`pwd`) USING BTREE,
  KEY `addr` (`addr`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

最左原则

  • where子句中字段的顺序不会影响索引的使用
1
2
3
4
5
6
7
8
SELECT
	*
FROM
	`user`
WHERE
	uname = '5f686bb79ff03'
AND dept_id = 91
AND phone = '14097548200';
https://static.duan1v.top/images/M3svut7faHiQZNK.png
MySQL学习笔记:组合索引-最左原则
  • where子句中,只能按照索引字段,从右向左依次截取字段,剩下的字段依次作为有效索引
1
KEY `index_user` (`dept_id`,`uname`,`phone`) USING BTREE

可以直接用的有效索引有:(dept_id,uname,phone),(dept_id,uname),(dept_id)

https://static.duan1v.top/images/HBC94xY1ODIPMmu.png
MySQL学习笔记:组合索引-最左原则

(dept_id,phone)中phone是走不上索引的,但是当满足MySQL的索引下推条件时,是可以减少回表次数,从而减少查询时间的。

https://static.duan1v.top/images/DcAJ5glGMOxupa2.png
MySQL学习笔记:组合索引-最左原则

mysql 批量插入 获取所有自增ID

背景

批量插入后,对刚插入的数据进行后续操作,需要获取所有插入的id,但执行sql只返回第一条id

思路

假设批量插入的数据的自增ID是连续的,则可以通过第一个自增ID获取所有自增ID

测试

理论上

批量插入的数据的自增ID是否是连续的,即插入过程中,单独插入其他数据,批量插入的自增ID是否连续

实践

  • 生成批量插入10w条数据的sql
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$s=<<<SQL
INSERT INTO `XXXX` (
    `test_id`,
    `operate_id`,
    `create_time`
)
VALUES
%s;
SQL;
$a=array();
for ($i=0;$i<100000;$i++){
    $a[]="('".rand(10000000,99999999)."', 'system', NOW())";
}
print_r(sprintf($s,implode(',',$a)));
exit(1);
  • navicat打开两个页面,一个是上面的sql,一个是一条单独插入的sql(这条sql的test_id,要大于上面sql里随机数的最大值,方便查看)
步骤
  • 先点击执行上面的sql(应该会执行20多秒吧),中间随机点击单条sql
  • 筛选单条sql中的test_id,可以发现开始几条都是小于批量的自增ID的
  • 在批量执行快结束的时候,插入的单条sql的自增ID是大于批量的,并没有单条sql的自增ID在批量中间
  • 所以批量插入的自增ID是连续的
  • 假设成立,可以这种方式获取批量插入的所有自增ID

Css的一些示例

表格中显示 a链接 自动换行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    table, table tr th, table tr td {
        border: 1px solid #0094ff;
    }

    table {
        width: 100%;
        min-height: 25px;
        line-height: 25px;
        text-align: center;
        border-collapse: collapse;
        margin-bottom: 20px;
    }

    table td {
        word-wrap: break-word;
        word-break: break-all;
    }

    table a {
        display: inline-block;
        word-wrap:break-word;
        overflow: hidden;
        text-overflow: ellipsis;
    }

垂直水平居中

1
2
3
display: flex;
justify-content: ceter;
align-items: center;