就像我解释的那样before ,我的 mysql 数据库服务器出现了一些问题。我会知道您的意见并有一些想法,因为我处于黑洞中,我不知道,因为正在发生服务器的行为。
我会尽量解释所有的环境。我有 1 个数据库,有很多表。我们用 java 制作了一个导出器工具,可以从数据库中导出所有数据。数据存储在5个不同的表中,我需要将数据连接到5个表中。这些是表格:
DB的结构是一个从一些传感器接收信息并存储的系统。
测量表:我们从传感器接收到的测量值。
+--------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| counter | char(2) | YES | | NULL | |
| datemeasurement_id | datetime | NO | MUL | NULL | |
| datereal_id | datetime | NO | MUL | NULL | |
| delayed | bit(1) | NO | | NULL | |
| frequency | tinyint(4) | YES | | NULL | |
| measuringentity_id | bigint(20) | NO | MUL | NULL | |
| real | bit(1) | NO | | NULL | |
| tamper | bit(1) | NO | | NULL | |
| value | float | NO | | NULL | |
+--------------------+------------+------+-----+---------+----------------+
measuring_entity 表:一个传感器可以测量不止一件事(温度、湿度)。这些就是实体。
+--------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| household_id | varchar(4) | NO | MUL | NULL | |
| operative | bit(1) | NO | | NULL | |
| type | char(20) | NO | | NULL | |
| unit | char(3) | NO | | NULL | |
| interval | float | YES | | NULL | |
+--------------+------------+------+-----+---------+----------------+
sensor_measuring_entity:一个传感器可以关联多个实体。
+--------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------+------+-----+---------+-------+
| sensor_id | bigint(20) | NO | PRI | NULL | |
| measuringentity_id | bigint(20) | NO | PRI | NULL | |
| version | bigint(20) | NO | | NULL | |
+--------------------+------------+------+-----+---------+-------+
传感器表:传感器的信息,与上表中的测量实体相关。
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| battery | bit(1) | NO | | NULL | |
| identifier | char(6) | NO | | NULL | |
| installationdate_id | datetime | NO | MUL | NULL | |
| lastreceiveddate_id | datetime | YES | MUL | NULL | |
| location_id | bigint(20) | NO | MUL | NULL | |
| operative | bit(1) | NO | | NULL | |
| tampererror | smallint(6) | NO | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
位置表:传感器的放置位置。
+------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| height | tinyint(4) | YES | | NULL | |
| operative | bit(1) | NO | | NULL | |
| place | char(15) | NO | MUL | NULL | |
| room | char(15) | NO | | NULL | |
| typesensor | char(15) | NO | | NULL | |
| formaster | bit(1) | YES | | NULL | |
+------------+------------+------+-----+---------+----------------+
导出信息的算法很重要,就像这样,交叉数据,尝试为我们可以在单独的 csv 文件中拥有的所有类型的传感器导出单独的信息。:
for (int i = 0; i < households.length; i++) {
openConnection();
for (int j = 0; j < values.length; j++) {
for (int k = 0; k < rooms.length; k++) {
if (places.length > 0) {
for (int l = 0; l < places.length; l++) {
for (int m = 0; m < height.length; m++) {
export(startDate2, endDate,
households[i], values[j],
rooms[k], places[l],height[m]);
}
}
} else {
for (int m = 0; m < height.length; m++) {
export(startDate2, endDate,
households[i], values[j],
rooms[k], null, height[m]);
}
}
}
}
try {
connection.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
public void export(String startTime, String endTime, String household,
String type, String room, String place, String height)
throws ExporterException {
String sql = buildSQLStatement(startTime, endTime, household, type,
room, place, height);
Statement query;
try {
query = connection.createStatement();
ResultSet result = query.executeQuery(sql);
…
(The exporting to csv code)
…
private String buildSQLStatement(String startTime, String endTime,
String household, String type, String room, String place,
String height) {
String sql = "select HIGH_PRIORITY m.datemeasurement_id, me.type, l.place, m.value, l.room, l.height, s.identifier "
+ "FROM measurement as m STRAIGHT_JOIN measuring_entity as me ON m.measuringentity_id = me.id "
+ "STRAIGHT_JOIN sensor_measuring_entity as sme ON me.id = sme.measuringentity_id "
+ "STRAIGHT_JOIN sensor as s ON sme.sensor_id = s.id "
+ "STRAIGHT_JOIN location as l ON l.id = s.location_id"
+ " WHERE m.datemeasurement_id "
+ " >"
+ "'"
+ startTime
+ "'"
+ " AND m.datemeasurement_id"
+ " <"
+ "'"
+ endTime
+ "'"
+ " AND m.measuringentity_id"
+ " IN (SELECT me.id FROM measuring_entity AS me WHERE me.household_id="
+ "'"
+ household
+ "'"
+ ")";
我的大问题是:有时这个带有来自数据库的代码的应用程序运行起来真的很慢。 MySQL 运行得非常慢,但有时 MYSQL 运行得非常快。我们无法理解为什么会发生这种行为差异。
例如,当它很慢时(CPU 的 0.3-0%),从数据库中导出所有数据可能需要大约 3 天的时间(大约 200.000 个查询),但正如我之前所说,有些时候服务器在 30-40 分钟内完成相同的工作(85% 的 CPU)。
我们看到的问题是,当行为缓慢时,mysql 花费大量时间处于“准备”状态(每个查询大约 140 秒),试图优化查询,但正如我所说,这种情况发生了只有某些时候。不是每次。
1016 | root | localhost:53936 | OptimAAL | Query | 10 | preparing | select HIGH_PRIORITY m.datemeasurement_id, me.type, l.place, m.value, l.room, l.height, s.identifier
这些是可以执行的查询之一:
EXPLAIN select HIGH_PRIORITY m.datemeasurement_id, me.type,
l.place,m.value, l.room, l.height, s.identifier
FROM measurement as m
STRAIGHT_JOIN measuring_entity as me ON m.measuringentity_id=me.id
STRAIGHT_JOIN sensor_measuring_entity as sme ON me.id=sme.measuringentity_id
STRAIGHT_JOIN sensor as s ON sme.sensor_id=s.id
STRAIGHT_JOIN location as l ON l.id=s.location_id
WHERE m.datemeasurement_id >'2012-01-19 06:19:00'
AND m.datemeasurement_id <'2012-01-19 06:20:00'
AND m.measuringentity_id IN (SELECT me.id FROM measuring_entity AS me
WHERE me.household_id='0022')
AND (height = '0')
AND (type = 'Brightness')
AND (place = 'Corner')
AND (room = 'Living room')
ORDER BY datemeasurement_id
这是解释的结果:
+----+--------------------+-------+-----------------+-----------------------------------------------+--------------------+---------+-------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-----------------+-----------------------------------------------+--------------------+---------+-------------------------------+------+-------------+
| 1 | PRIMARY | m | range | FK93F2DBBC6292BE2,FK93F2DBBCA61A7F92 | FK93F2DBBC6292BE2 | 8 | NULL | 4 | Using where |
| 1 | PRIMARY | me | eq_ref | PRIMARY | PRIMARY | 8 | OptimAAL.m.measuringentity_id | 1 | Using where |
| 1 | PRIMARY | sme | ref | PRIMARY,FK951FA3ECA61A7F92,FK951FA3ECF9AE4602 | FK951FA3ECA61A7F92 | 8 | OptimAAL.m.measuringentity_id | 1 | Using index |
| 1 | PRIMARY | s | eq_ref | PRIMARY,FKCA0053BA3328FE22 | PRIMARY | 8 | OptimAAL.sme.sensor_id | 1 | |
| 1 | PRIMARY | l | eq_ref | PRIMARY,place | PRIMARY | 8 | OptimAAL.s.location_id | 1 | Using where |
| 2 | DEPENDENT SUBQUERY | me | unique_subquery | PRIMARY,FK11C7EA07E6EB51F2 | PRIMARY | 8 | func | 1 | Using where |
+----+--------------------+-------+-----------------+-----------------------------------------------+--------------------+---------+-------------------------------+------+-------------+
显然,如果我们更改日期间隔的值,数据量会增加很多,因为我们的数据库中有大约 100 万个测量值。
我尝试了一切:
更改 mysQL 配置文件 (/etc/my.cnf):
[mysqld]
#bind-address = 141.21.8.197
max_allowed_packet = 128M
sort_buffer_size = 512M
max_connections=500
query_cache_size = 512M
query_cache_limit = 512M
query-cache-type = 2
table_cache = 80
thread_cache_size=8
key_buffer_size = 512M
read_buffer_size=64M
read_rnd_buffer_size=64M
myisam_sort_buffer_size=64M
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size=700M
innodb_additional_mem_pool_size=20M
datadir=/data/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#Enable logs
log = /var/log/mysql/mysql-log.log
log-error = /var/log/mysql/mysql-error.log
long_query_time = 1
log-slow-queries = /var/log/mysql/mysql-slow.log
[mysqld_safe]
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
如您所见,我尝试了所有方法,但我不知道该怎么做才能确保服务器始终保持快速。
这些是服务器的信息:
MySQL version: 5.1.61-log / x86_64
RAM: 8 GB
OS: CentOS release 6.2 (Final)
CPU: 4 Cores / Xeon E6510 @ 1.73GHz
非常感谢您的帮助,
编辑:
我想补充一点,现在对我来说最大的问题是为什么服务器会发生不同的行为。因为我知道可以优化查询,但有时使用这段代码工作得非常快。
我现在的噩梦是知道为什么有时工作速度很快,而不是总是。现在我正在与 IT 人员核实是否可能是硬件访问问题、硬盘问题或类似问题。
看起来也可能是 SQL 配置的问题,或者它在 MYSQL 中的查询优化器的问题,但我无法发现我的黑洞的解决方案是什么。
非常感谢您的帮助
最佳答案
我能想到您可以做的一些优化。
首先,使用绑定(bind)变量和准备好的语句。
PreparedStatment stmt = connection.prepareStatement(
"select HIGH_PRIORITY m.datemeasurement_id, me.type, l.place, m.value, l.room, l.height, s.identifier "
+ "FROM measurement as m STRAIGHT_JOIN measuring_entity as me ON m.measuringentity_id = me.id "
+ "STRAIGHT_JOIN sensor_measuring_entity as sme ON me.id = sme.measuringentity_id "
+ "STRAIGHT_JOIN sensor as s ON sme.sensor_id = s.id "
+ "STRAIGHT_JOIN location as l ON l.id = s.location_id"
+ " WHERE m.datemeasurement_id > ? "
+ " AND m.datemeasurement_id < ? "
+ " AND m.measuringentity_id IN (SELECT me.id FROM measuring_entity AS me WHERE me.household_id= ? )";
stmt.setDate(1, startDate);
stmt.setDate(2, endDate);
stmt.setString(3, household);
stmt.executeQuery();
其次,删除 IN - 您不能在此处针对 measuring_entity 使用单独的联接吗? IN 通常表现不佳。
第三,你能使用批处理来执行你的插入吗?批量插入应该会显着提高速度。
这些是我能即兴想到的几件事。如果您的查询未在 Java 端进行优化,那么世界上所有的 SQL 调优都无济于事。
关于java - MySQL 在 Preparing Statement 中以非常奇怪的行为被阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10447009/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg