一个在mysql中查询过慢的问题,我的查询语句是多表联合查询.语句写法如下.感觉不是很好.能否优化???

一个在mysql中查询过慢的问题,我的查询语句是多表联合查询.语句写法如下.感觉不是很好.能否优化???,第1张

问题

我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?

实验

我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤。

写个简单的脚本,制造一批带主键和不带主键的表:

执行一下脚本:

现在执行以下 SQL 看看效果:

...

执行了 16.80s,感觉是非常慢了。

现在用一下 DBA 三板斧,看看执行计划:

感觉有点惨,由于 information_schema.columns 是元数据表,没有必要的统计信息。

那我们来 show warnings 看看 MySQL 改写后的 SQL:

我们格式化一下 SQL:

可以看到 MySQL 将

select from A where A.x not in (select x from B) //非关联子查询

转换成了

select from A where not exists (select 1 from B where B.x = a.x) //关联子查询

如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:

select from A where A.x not in (select x from B where ...) //非关联子查询:1. 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中,建好索引2. 扫描 A 表中的记录,与临时表 C 中的记录进行比对,直接在索引里比对,

而关联子查询就需要循环迭代:

select from A where not exists (select 1 from B where B.x = a.x and ...) //关联子查询扫描 A 表的每一条记录 rA:     扫描 B 表,找到其中的第一条满足 rA 条件的记录。

显然,关联子查询的扫描成本会高于非关联子查询。

我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化,MATERIALIZATION),但MySQL 认为不缓存更快,我们就需要给予 MySQL 一定指导。

...

可以看到执行时间变成了 0.67s。

整理

我们诊断的关键点如下:

\1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息。

\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。

\3. 我们增加了 hint,指导 MySQL 正确进行优化判断。

但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。

首先你的机器上得装有一款数据库,通常是Oracle,Ms sql,MySQL等,不考虑框架等,jsp中主要是利用jdbc进行连接数据库

1,打开数据库服务(你已经设计好了数据库)

2,在class-path中添加相应数据库的连接jar包,

3.利用jdbc进行 *** 作

例如:

JDBC - 环境设置:

请确认您已完成以下设置:

核心JAVA安装

SQL 或 MySQL数据库安装

除上述者外,需要建立一个数据库,为本程测试项目使用。假设这是EMP,在同一个数据库上创建表Employees。

创建JDBC应用程序:

参与建立一个JDBC应用程序,本教程中按六个步骤进行:

导入包:

这需要你有软件包包含了数据库编程所需的JDBC类。大多数情况下,使用import java.sql.* 就足够了,如下所示:

//STEP 1. Import required packages

import java.sql.*

注册JDBC驱动程序:

这需要初始化驱动程序,这样就可以打开与数据库的通信信道。以下是代码片段实现这一目标:

//STEP 2: Register JDBC driver

Class.forName("com.mysql.jdbc.Driver")

打开一个连接:

这需要使用DriverManager.getConnection()方法来创建一个Connection对象,它代表一个物理连接的数据库,如下所示:

//STEP 3: Open a connection

// Database credentials

static final String USER = "username"

static final String PASS = "password"

System.out.println("Connecting to database...")

conn = DriverManager.getConnection(DB_URL,USER,PASS)

执行一个查询:

这需要使用一个对象类型Statement或PreparedStatement构建,并提交一个SQL语句到数据库。如下:

//STEP 4: Execute a query

System.out.println("Creating statement...")

stmt = conn.createStatement()

String sql

sql = "SELECT id, first, last, age FROM Employees"

ResultSet rs = stmt.executeQuery(sql)

如果有一个SQL UPDATE,INSERT或DELETE语句,那么需要下面的代码片段:

//STEP 4: Execute a query

System.out.println("Creating statement...")

stmt = conn.createStatement()

String sql

sql = "DELETE FROM Employees"

ResultSet rs = stmt.executeUpdate(sql)

从结果集中提取数据:

这一步是必需的情况下,从数据库中获取数据。可以使用适当的ResultSet.getXXX()方法来检索的数据结果如下:

//STEP 5: Extract data from result set

while(rs.next()){

//Retrieve by column name

int id = rs.getInt("id")

int age = rs.getInt("age")

String first = rs.getString("first")

String last = rs.getString("last")

//Display values

System.out.print("ID: " + id)

System.out.print(", Age: " + age)

System.out.print(", First: " + first)

System.out.println(", Last: " + last)

}

清理环境:

应该明确地关闭所有的数据库资源,对依赖于JVM的垃圾收集如下:

//STEP 6: Clean-up environment

rs.close()

stmt.close()

conn.close()

现在比较大型点的系统基本上是AP+DB的架构: AP指应用程序,DB指数据库端

AP放在一个服务器上,DB放在另一个服务器上

当一个系统比较大,访问的用户数量比较多的时候,比如QQ,上亿用户.

这时一个服务器就吃不消了,这样就想到多个服务器跑同一个AP应用.

DB端也一样.

linux集群 指的就是多个服务器跑同一个AP应用,系统管理员的工作

数据库集群 指的就是多个服务器跑同一个DB数据库.数据库管理员的工作

linux集群基础就要熟悉linux系统.

数据库集群基础就要熟悉具体的数据库如oracle,db2,sysbase.mysql.等

0基础可以学,只是要花时间.0基础想搞到集群估计得花3个月时间.这还是要有环境的,有人指导才行.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7239114.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存