最近发现,我们有些环境的tomcat应用启动非常缓慢,大部分在3-5分钟,有个测试环境更加阶段,要十几分钟才能启动完成。经过仔细分析,是一个查询INFORMATION_SCHEMA库中数据字典信息的查询异常缓慢,该语句如下:

SELECT
c.COLUMN_NAME,
c.TABLE_NAME
FROM
information_schema.TABLE_CONSTRAINTS AS t,
information_schema.KEY_COLUMN_USAGE AS c
WHERE
t.TABLE_NAME = c.TABLE_NAME
AND t.TABLE_SCHEMA = c.CONSTRAINT_SCHEMA
AND t.CONSTRAINT_SCHEMA = 'hs_tatrade2'
AND t.CONSTRAINT_TYPE = 'PRIMARY KEY'

以前从来都没遇到这种问题,也很少关心mysql数据字典查询的性能问题,因为几乎没有遇到过。

查看show processlist,一直在after opening table等待。。。。

看了下执行计划以及information_schema中表结构的定义,因为都是内存表,都没有索引,这两张表都只有数百条记录,按说即使没有索引也不会这么慢。。。

经网上搜寻,有人有不少帖子提及是因为innodb_stats_on_metadata=ON导致查询information_schema时更新统计信息的原因。经测试,不是这个原因(其实,我现在相信网上80%以上的所谓分析帖子都是理论上的测试,并不是真正遇到,尤其是所谓的很多专家)。

再次寻找到mysql官方文档,https://dev.mysql.com/doc/refman/5.7/en/information-schema-optimization.html,如下:

8.2.3 Optimizing INFORMATION_SCHEMA Queries

1) Try to use constant lookup values for database and table names in the WHERE clause

You can take advantage of this principle as follows:

  • To look up databases or tables, use expressions that evaluate to a constant, such as literal values, functions that return a constant, or scalar subqueries.

  • Avoid queries that use a nonconstant database name lookup value (or no lookup value) because they require a scan of the data directory to find matching database directory names.

  • Within a database, avoid queries that use a nonconstant table name lookup value (or no lookup value) because they require a scan of the database directory to find matching table files.

This principle applies to the INFORMATION_SCHEMA tables shown in the following table, which shows the columns for which a constant lookup value enables the server to avoid a directory scan. For example, if you are selecting from TABLES, using a constant lookup value for TABLE_SCHEMA in the WHERE clause enables a data directory scan to be avoided.

Table Column to specify to avoid data directory scan Column to specify to avoid database directory scan
COLUMNS TABLE_SCHEMA TABLE_NAME
KEY_COLUMN_USAGE TABLE_SCHEMA TABLE_NAME
PARTITIONS TABLE_SCHEMA TABLE_NAME
REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_NAME
STATISTICS TABLE_SCHEMA TABLE_NAME
TABLES TABLE_SCHEMA TABLE_NAME
TABLE_CONSTRAINTS TABLE_SCHEMA TABLE_NAME
TRIGGERS EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE
VIEWS TABLE_SCHEMA TABLE_NAME

意思就是查询上述这些表的时候,务必带上TABLE_SCHEMA=或者XXX_SCHEMA,以避免数据目录扫描。而我们的场景刚好是TABLE_CONSTRAINTS没有使用TABLE_SCHEMA,虽然关联使用了TABLE_SCHEMA,但这是没有用的。

经过将SQL更改为如下:

SELECT
c.COLUMN_NAME,
c.TABLE_NAME
FROM
information_schema.TABLE_CONSTRAINTS AS t,
information_schema.KEY_COLUMN_USAGE AS c
WHERE
t.TABLE_NAME = c.TABLE_NAME
AND t.TABLE_SCHEMA = c.CONSTRAINT_SCHEMA
AND t.TABLE_SCHEMA = 'hs_tatrade2'
AND c.TABLE_SCHEMA = 'hs_tatrade2'
AND t.CONSTRAINT_TYPE = 'PRIMARY KEY'

瞬间就飞快了。

mysql查询INFORMATION_SCHEMA表很慢的性能优化的更多相关文章

  1. MySQL查询数据表中数据记录(包括多表查询)

    MySQL查询数据表中数据记录(包括多表查询) 在MySQL中创建数据库的目的是为了使用其中的数据. 使用select查询语句可以从数据库中把数据查询出来. select语句的语法格式如下: sele ...

  2. mysql查询锁表及解锁

    SHOW PROCESSLIST; KILL ; 锁表网上解释: 这牵涉到mysql的事务,简单通俗的话,就这样给你解释有一个任务序列控制sql语句的执行,第一次有select的语句查询表a,mysq ...

  3. mysql 查询锁表

    1)使用情景“判断通过后写入数据库”,这个一般是不会有问题的, 但并发访问的时候就不太好搞.因为写入(insert)是需要时间的,假设现在有两个并发请求,(假设第一个访问是最后一个符合条件的写入请求, ...

  4. (转) mysql数据库引擎:MyISAM和InnoDB(性能优化)

    转自 http://yuwensan126.iteye.com/blog/1138022 Mysql 数据库中,最常用的两种引擎是innordb和myisam.Innordb的功能要比myiasm强大 ...

  5. Oracle 学习总结 - 表和索引的性能优化

    表的性能 表的性能取决于创建表之前所应用的数据库特性,数据库->表空间->表,创建数据库时确保为每个用户创建一个默认的永久表空间和临时表空间并使用本地管理,创建表空间设为本地管理并且自动段 ...

  6. Oracle多表连接效率,性能优化

    Oracle多表连接,提高效率,性能优化 (转) 执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只 ...

  7. 关于Mysql 查询所有表的实时记录用于对比2个MySQL 库的数据是否异步

    Xu言: 今天,为了研究一个MySQL主从同步开机后报错 问题,如下图 故障原因分析: 经过分析,可能是主从服务器开机顺序导致.(有待下次断电再次测试) 主从错误提示:日志读取错误的问题.解决方法:更 ...

  8. mysql查询锁表语句

    processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令. 1.      进入mysql/bin目录下输入mysqladmin process ...

  9. mysql查询所有表名

    mysql使用sql查询表名的两种方法: 1.show tables; 2.SELECT TABLE_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WH ...

随机推荐

  1. python threading acquire release

    线程同步 //test.py import threading import time exitFlag = 0 class myThread (threading.Thread): def __in ...

  2. 基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0

    基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0 目录 1. 开发环境2. 主要功能逻辑介绍3. 框架功能简介 4. 数据库的创建 5. 框架模块详细介绍6. Tes ...

  3. Dockerfile详解(三)

    1.概述 创建Docker镜像的方式有三种 docker commit命令:由容器生成镜像: Dockerfile文件+docker build命令: 从本地文件系统导入:OpenVZ的模板. 关于这 ...

  4. Window.sessionStorage - Web API 接口参考 | MDN

    参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/sessionStorage sessionStorage 属性允许你访问一个 s ...

  5. jar包的读取

    昨天在做项目插件的时候,因为会用到jar包中的一个文件来初始化程序.并且以后还是会访问这个文件,所以就想到干脆吧文件拷贝到指定目录.在拷贝的时候也费了好一会时间,这里涉及到了jar文件的操作,在这里记 ...

  6. GE与POST方法区别

    1.用途. GET方法一般用于查询并获取信息,这意味着它是幂等的(对同一个url的多个请求,返回结果完全一样),因为没有修改资源状态,所以它是安全的.而POST一般用于更新资源信息,既不是幂等,也不是 ...

  7. [Unit Test] Unit Test Brief Introduction

    Levels of Testing- Acceptance- Performance- Functional- Integration- Unit Why Unit Testing- Feedback ...

  8. centos python2升级为python3 升级旧版本django

    阿里云centos python3 及django的配置 安装python3后 pip 会把下载的包安入python2.7 下面解决该问题 python3.5安装1,安装依赖包#yum install ...

  9. STL算法中函数对象和谓词

    函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列 ...

  10. 安装模块时报错“error: Microsoft Visual C++ 14.0 is required…”

    安装pymssql时报错:在安装的过程中遇到了“error: Microsoft Visual C++ 14.0 is required…” 解决办法: 进入https://www.lfd.uci.e ...