为什么select count(*)在myisam比innodb里效率高,innodb里如何优化?

因为MySQL的MyISAM引擎在内部维护了一个计数器,当select count(*)其实就是拿到这个计数器的最新数值返回即可,而innodb却是要实时统计的。

那么,为什么innodb存储引擎不也维护一个计数器呢?

那是因为对于InnoDB这样的事务性存储引擎,存储准确的行数是不太现实的,因为多个事务可能同时发生,每个事务都有可能影响计数。 InnoDB不保留表中的行数,因为并发事务可能同时“看到”不同的行数。因此,SELECT COUNT(*)语句只计算当前事务可见的行。

为了处理SELECT COUNT(*)语句,InnoDB扫描表的索引,如果索引不是完全在缓冲池中,那么这将花费一些时间。

经过实践发现,不同的服务器配置下,当innodb表的行数达到数百万、数十万甚至数万的情况下,select count(*) 就会非常慢(需要十几秒甚至几分钟!),那么如何优化呢?

建议采用二级索引速度会比用主键索引更快。

在InnoDB引擎中,当我们通过二级索引统计数据的时候,无需扫描数据文件(二级索引存储指定字段的索引,实际的指向位置是主键索引。);而通过主键索引统计数据时,由于主键索引与数据文件存放在一起,所以每次都会扫描数据文件,所以主键索引统计没有二级索引效率高。

innodb表中除了主键ID之外,再找一个字段进行索引,然后在查询的时候使用select count(第二索引的字段),查询效率会大大提高。

0

堆表和索引组织表区别

堆表(heap table)数据插入时时存储位置是随机的,主要是数据库内部块的空闲情况决定,获取数据是按照命中率计算,全表扫表时不见得先插入的数据先查到。
索引表(iot)数据存储是把表按照索引的方式存储的,数据是有序的,数据的位置是预先定好的,与插入的顺序没有关系。
索引表的查询效率逼堆表高(相当于查询索引的效率),插入数据的速度比堆表慢。
索引表适用场景:
适用于信息检索、空间和OLAP程序。
1、 代码查找表。
2、 经常通过主码访问的表。
3、 构建自己的索引结构。
4、 加强数据的共同定位,要数据按特定顺序物理存储。
5、 经常用between…and…对主码或唯一码进行查询。数据物理上分类查询。如一张订单表,按日期装载数据,想查单个客户不同时期的订货和统计情况。

常用数据库支持情况:
Oracle支持堆表,也支持索引组织表
PostgreSQL只支持堆表,不支持索引组织表
Innodb只支持索引组织表

0

MySQL里查看某张表的建表语句

0

java动态代理面试题

题目

1.动态代理的应用场景?
2.aop就是代理吗?aop和代理的关系?
3.spring aop中代理有哪4种实现方式?区别?
4.代理底层操作的是什么?
5.如何查看某个class类的jvm虚拟机指令码?aspectj和instrumentation实现的逻辑是什么?它们和java proxy、cglib有什么区别?
6.动态代理技术栈图?

答案

  • 基于Class字节码透视java动态代理本质 https://www.youtube.com/watch?v=9uEIOpbi-lQ&list=PLtLteuiQZN4P_H0HcrqjgBAsRepMRnyQb
  • 问题5的答案:①aspectj和instrumentation是跳过代码层面直接在class文件里织入字节码指令,而java proxy和cglib是生成新的class。 ②前面两个是需要用到反射的。③共同点就是它们底层都是通过字节码实现的。 ④ 其中cglib和instrumentation对字节码的操作都是通过ASM实现的。java proxy 和 aspectj是自己操作字节码。
  • 动态代理技术栈图:

Java Proxy示例代码

使用javap -c ProxyTest.class查看字节码信息

0

Chocolatey的离线安装教程

前言

前面在Windows里使用Chocolatey像在Linux里那样快速方便的安装软件介绍了Chocolatey的功能和使用,但是实际操作下来,很多情况会导致直接在线安装失败,于是就需要离线安装。

步骤

1.下载Nupkg 包(3.88M),链接:https://packages.chocolatey.org/chocolatey.0.10.15.nupkg
(其他版本点击 https://chocolatey.org/packages/chocolatey )

2.新建记事本文件,并改名为setup.ps1,下面是内容:

3.修改第46行:$localChocolateyPackageFilePath = ‘C:\Users\123\Desktop\chocolatey.0.10.15.nupkg’
其中的chocolatey.0.10.15.nupkg是第1步下载的nupkg包,路径改成你下载的文件的路径。

4.修改第277行,将这一行注释掉(前边加#)或者删掉,目的是如果nupkg文件不存在不要下载。然后保存。

5.按Windows键快捷输入powershell,右键管理员运行。执行:iex C:\Users\123\Desktop\setup.ps1
大约5秒后,如下图所示即为安装成功。

+1

Windows里使用Chocolatey像在Linux里那样快速方便的安装软件

示例

使用 Chocolatey 安装 Bandizip

没错,只需要输入一行命令,稍等几分钟,Bandizip 已经在你的系统中装好啦。

安装 Chocolatey

要想这样通过命令行来一键安装程序,我们借助的是 Chocolatey 这款软件包管理器。它事实上是为了习惯于 Linux 的程序员们准备的,因为在 Linux 中安装程序,通常都只需要一条安装命令就可以完成。不过,这丝毫不影响每一个人来尝试一下。

Chocolatey 自身的安装很方便,一共有三步:

  1. 开始菜单中搜索 cmd,选择「命令提示符」
  2. 右键菜单或在右边菜单选择「以管理员身份运行」
  3. 复制下面这段内容,回车执行

OK 准备就绪。

前面的安装命令来自 官网的安装界面,如果有更新,还是以官网的为准。

第一次尝试

接下来,我们可以继续在这个窗口中,尝试安装我们的第一个程序。输入:

稍等片刻,Bandizip 程序就安装好了。你可以在桌面上看到它的快捷方式。

装机从此不再难

每次拿到一台新的电脑,快速安装上所有自己需要的程序是一件非常非常耗时间的事情。

如果去国内各大第三方下载站,或者电脑管家、百度的安装工具,它们很多都会把原生的安装包进行修改,加入自己的广告或其他私货;总之,下载软件还是最好去各自的官网,这样才能最好地避免病毒、保护隐私。

然而,要一个个软件分别去官网下载,既无聊,又费心。下载安装包之后,还需要手动一次次地点击「下一步」,直到全部安装完成。

Chocolatey 就可以比较好地解决这些烦恼。因为你可以:

把你想要安装的程序一起写上,十个,二十个,都没有关系。把它丢在一边跑着,你可以出去吃个冰淇淋,回来就都装上了。

还有一些命令

在安装的过程中,你应该已经发现 Chocolatey 的命令非常语义化。

先以 choco 开头,告诉系统我要使用 Chocolatey 了,然后用 install 表明我要安装一个程序,最后跟上需要安装的程序名称即可。中间的 --yes 意味着对 Chocolatey 安装过程的认可,如果不加,Chocolatey 会在安装的每一个步骤前停下来问你是否同意继续。

所以,这个命令理解下来就是:「召唤」Chocolatey,请执行「安装」,我「同意」你的一切行为,安装的内容是「Bandizip 和 Firefox」。

除了安装,你肯定还关心怎么卸载。要是想要卸载一个已经安装的程序,只需要执行:

为了便于管理,我们有时候需要查看所有程序的列表。想知道自己用 Chocolatey 装了哪些程序,可以这样写:

需要更新程序时,可以先检查一下哪些应用需要更新,使用 outdated 命令:

这样就会把所有「过期」的应用全部列出来,可以按需更新。升级与安装的命令格式相似:

你也可以尝试一键升级所有程序,命令同样非常语义化,执行「升级」、「允许」操作、「所有」应用:

现在,你可以不必担心每一个程序是否是最新版,因为你可以时不时运行一下更新命令;你也不用担心程序卸载不干净了,使用 Chocolatey 安装的程序,就可以用 Chocolatey 卸载。

知其所以然

前面安装的时候提到过,Chocolatey 跟其他第三方软件管理器不同之处在于,其他软件管理器经常修改原来的安装包,从而可以夹带自己的广告,并且经常安装好之后发现并不是最新版本。但是 Chocolatey 不但使用官网链接下载,而且会在下载完成后使用数字摘要技术检查安装包是否跟官网上的完全一致,所以,你使用 Chocolatey 安装的就是最新纯净官网版本。

此外,通过使用 info 命令,你还可以查看程序的详细信息,便于你确认是否需要使用 Chocolatey 来安装这个程序:

得到 Tim 的详细信息如下:

在这里列出了 Tim 的软件描述、更新时间、用户协议、官网链接、下载数、用于完整性检查的数字摘要,以及软件包的认证状态和测试状态。这些信息可以用来确认 Chocolatey 上的这个软件包是否可靠。

它包揽了一切

现在,我的 Windows 软件基本上全靠 Chocolatey 管理了。每隔一段时间,我会用 list 命令导出一下已安装的软件,需要配置新电脑的时候,只要把这份导出的列表稍作整理,就可以用 install 命令一下子全部装上了。这样也可以让公司和家里的 Windows 电脑保持一致的使用手感。

不过,仍有一些软件没有在 Chocolatey 上提供。我需要手动安装的软件包括:

  • QQ(不过有 Tim)
  • 微信
  • 搜狗输入法
  • 火绒安全
  • Visual Studio
  • Office

此外,还有一些软件需要从微软应用商店下载,自然也不会出现在 Chocolatey 中。无论如何,Chocolatey 绝对是一种值得尝试的软件管理方式。

0

MySQL里concat()、concat_ws()、group_concat()三个函数的使用比较

本文中使用的例子均在下面的数据库表tb_user下执行:

一、concat()函数

1、功能:将多个字符串连接成一个字符串。

2、语法:concat(str1, str2,…)

返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

3、举例:

SELECT CONCAT(u.id, ',', u.username, ',', u.org_id) as cus FROM `tb_user` u ORDER BY u.id

中间有一行为null是因为表中有一行的org_id值为null。

可以看到中间的分隔符需要自己手动一个个设置?——于是可以指定参数之间的分隔符的concat_ws()来了!!!

二、concat_ws()函数

1、功能:和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)

2、语法:concat_ws(separator, str1, str2, …)

说明:第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。

3、举例:

例3:我们使用concat_ws()将 分隔符指定为逗号,达到与例2相同的效果:

SELECT CONCAT_WS(',', u.id, u.username, u.org_id) as cus FROM `tb_user` u ORDER BY u.id

例4:把分隔符指定为null,结果全部变成了null:

SELECT CONCAT_WS(null, u.id, u.username, u.org_id) as cus FROM `tb_user` u ORDER BY u.id

三、group_concat()函数

前言:在有group by的查询语句中,select指定的字段要么就包含在group by语句的后面,作为分组的依据,要么就包含在聚合函数中。

例5:

假设要查询在同一组织下的用户名,可以这样查询:

SELECT u.username, u.org_id as orgId FROM `tb_user` u ORDER BY u.org_id

例6:

但是这样同一个组织出现多次,看上去非常不直观。有没有更直观的方法,既让每个组织id都只出现一次,又能够显示所有的名字相同的人的姓名呢?——使用group_concat()

1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )

说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

3、举例:

SELECT GROUP_CONCAT(u.username), u.org_id as orgId FROM `tb_user` u GROUP BY u.org_id
0

java代码获取Linux 磁盘空间的使用情况

0