Mysql在时间值范围内连接(无精确关系)
我正在评估一个研究项目的日志文件,并将它们插入MySQL数据库。 现在我有了一个查询,需要在没有精确匹配值的情况下连接来自其他表的数据 “logdata”表包含我必须分析的移动设备的数据,“basepositions”包含基站的GPS坐标。在“logdata”的两个数据字段中,记录了相应基站的发送方位置。存在的问题是:基站的位置随时间略有变化(GPS波动,只有几度),因此我必须使用下面的查询中所示的中间操作来查找正确的条目。这并不完美,但只有大约100个基站,因此成本可以承受 第二个联接中也存在相同的问题。在那里,我必须从另一个表中获取有效性标志。这里的问题是:两个日志大约每秒写入一次,但并不同步。因此,我必须扫描相应的行,再次使用介于和之间的时间范围1秒 由于行数的原因,第二次扫描使我的执行时间激增。 我认为扩散相关性是这里的问题 这两个表都有下面概述中给出的索引 有没有办法加快查询速度?由于性能问题,在我的数据库设置中,现在需要30小时才能返回大约20000行 谢谢你的帮助 日志数据(约300.000.000条记录): 基本位置(约100个条目): 有效期(约200.000.000条): 到目前为止,我的问题是:Mysql在时间值范围内连接(无精确关系),mysql,performance,join,range,Mysql,Performance,Join,Range,我正在评估一个研究项目的日志文件,并将它们插入MySQL数据库。 现在我有了一个查询,需要在没有精确匹配值的情况下连接来自其他表的数据 “logdata”表包含我必须分析的移动设备的数据,“basepositions”包含基站的GPS坐标。在“logdata”的两个数据字段中,记录了相应基站的发送方位置。存在的问题是:基站的位置随时间略有变化(GPS波动,只有几度),因此我必须使用下面的查询中所示的中间操作来查找正确的条目。这并不完美,但只有大约100个基站,因此成本可以承受 第二个联接中也存在
SELECT
logdata.unit,
logdata.timestamp,
logdata.d1,
logdata.d2,
cast(logdata.d3/10000000 as decimal(15, 10)),
cast(logdata.d4/10000000 as decimal(15, 10)),
logdata.d5,
logdata.d6,
logdata.d7,
logdata.d8,
cast(logdata.d9/10000000 as decimal(15, 10)),
cast(logdata.d10/10000000 as decimal(15, 10)),
BASEID,
validity.d1
FROM
logdata
JOIN
basepositions
ON
cast(GPSLATITUDE / 10000000 as decimal(15,10)) BETWEEN cast(d3 / 10000000 as decimal(15,10)) - 0.0001 AND cast(d3 / 10000000 as decimal(15,10)) + 0.0001
AND
cast(GPSLONGITUDE / 10000000 as decimal(15,10)) BETWEEN cast(d4 / 10000000 as decimal(15,10)) - 0.0001 AND cast(d4 / 10000000 as decimal(15,10)) + 0.0001
JOIN
validity
ON
validity.unit = logdata.unit
AND
validity.logid = 12345
AND
validity.timestamp BETWEEN logdata.timestamp - 500 AND logdata.timestamp + 499
WHERE
logdata.unit = "IVS${IVS}"
AND
logdata.logid = 111222
AND
BASEID = 012;
指数:
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| logdata | 0 | PRIMARY | 1 | id | A | 301433830 | NULL | NULL | | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 1 | unit | A | 18 | 6 | NULL | YES | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 2 | logid | A | 18 | NULL | NULL | YES | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 3 | timestamp | A | 301433830 | NULL | NULL | YES | BTREE | | |
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
编辑(注释字段太小):
我认为问题在于构造的连接。EXPLAIN EXTENDED显示,查询优化器正在将所有三个表连接在一起,这意味着要查看300.000.000*200.000.000*100行。
当我将带有“validity”的连接重写为子查询时,mysql只是将“logdata”和“basepositions”连接起来。
我认为数据类型的更改可能是以后优化的一个因素,但首先我认为我必须通过优化查询计划来获得一些运行时类。
我没有足够的经验知道我可以做些什么来进一步优化这个查询。
对“validity”上的时间戳的单个查询将立即返回。
对基站位置的单一查询也非常快速。
我不知道如何说服mysql首先过滤并加入我的查询
编辑2:
这是你要的创意。我用“显示索引自”
“有效性”指标:
“基本位置”的索引:
解释上述问题:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE basepositions const PRIMARY PRIMARY 4 const 1 100.00
1 SIMPLE logdata ref unit_logid_timestamp unit_logid_timestamp 14 const,const 4150932 100.00 Using where
1 SIMPLE validity ref unit_logid_timestamp unit_logid_timestamp 14 const,const 3294136 100.00 Using where
解释(添加lat/lon索引后):
嗯,有很多东西可以提高这个查询的性能。我现在还不打算发布答案,因为我需要一些澄清。长话短说:您需要索引、规范化和数据类型更改。是否可以将纬度和经度数据类型更改为
DECIMAL
s?请参阅编辑(注释字段太小)。问题是连接
s未使用索引;如果他们正在使用索引,则查询所用的时间应少于1秒。basepositions
上的JOIN
无法使用索引,因为您在比较数据之前正在修改数据;如果您更改了数据类型,因此不需要对其进行转换,则可以使用索引<代码>有效性可能需要更好的索引。请发布一个解释,说明查询和所有表上的索引;问题中的索引与上面的表不匹配。我在第二次编辑中提供了这些信息。我将尝试更改baseposition中坐标的数据类型。我怎样才能知道索引是否真的被使用了?因为explain声明它将使用unit_logid_时间戳索引。谢谢你迄今为止的帮助!目前,这对我来说是一个真正的阻碍。EXPLAIN
中的ref
列通常是索引使用方式的最佳指示器。对于logdata
和validity
而言,ref
是const,const
,这意味着它正在使用索引的前两个部分(它没有使用时间戳
部分),并且它正在将。查询计划显示查询已尽可能地优化,但仍然可以做得更好。基本上,需要为lat/lon字段上的第一个JOIN
创建索引。
SELECT
logdata.unit,
logdata.timestamp,
logdata.d1,
logdata.d2,
cast(logdata.d3/10000000 as decimal(15, 10)),
cast(logdata.d4/10000000 as decimal(15, 10)),
logdata.d5,
logdata.d6,
logdata.d7,
logdata.d8,
cast(logdata.d9/10000000 as decimal(15, 10)),
cast(logdata.d10/10000000 as decimal(15, 10)),
BASEID,
validity.d1
FROM
logdata
JOIN
basepositions
ON
cast(GPSLATITUDE / 10000000 as decimal(15,10)) BETWEEN cast(d3 / 10000000 as decimal(15,10)) - 0.0001 AND cast(d3 / 10000000 as decimal(15,10)) + 0.0001
AND
cast(GPSLONGITUDE / 10000000 as decimal(15,10)) BETWEEN cast(d4 / 10000000 as decimal(15,10)) - 0.0001 AND cast(d4 / 10000000 as decimal(15,10)) + 0.0001
JOIN
validity
ON
validity.unit = logdata.unit
AND
validity.logid = 12345
AND
validity.timestamp BETWEEN logdata.timestamp - 500 AND logdata.timestamp + 499
WHERE
logdata.unit = "IVS${IVS}"
AND
logdata.logid = 111222
AND
BASEID = 012;
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| logdata | 0 | PRIMARY | 1 | id | A | 301433830 | NULL | NULL | | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 1 | unit | A | 18 | 6 | NULL | YES | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 2 | logid | A | 18 | NULL | NULL | YES | BTREE | | |
| logdata | 1 | unit_logid_timestamp | 3 | timestamp | A | 301433830 | NULL | NULL | YES | BTREE | | |
+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
+-------------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| validity | 0 | PRIMARY | 1 | id | A | 194863653 | NULL | NULL | | BTREE | | |
| validity | 1 | unit_logid_timestamp | 1 | unit | A | 18 | 6 | NULL | YES | BTREE | | |
| validity | 1 | unit_logid_timestamp | 2 | logid | A | 18 | NULL | NULL | YES | BTREE | | |
| validity | 1 | unit_logid_timestamp | 3 | timestamp | A | 194863653 | NULL | NULL | YES | BTREE | | |
+-------------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
+----------------------+------------+---------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------------+------------+---------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| basepositions | 0 | PRIMARY | 1 | ID | A | 109 | NULL | NULL | | BTREE | | |
+----------------------+------------+---------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE basepositions const PRIMARY PRIMARY 4 const 1 100.00
1 SIMPLE logdata ref unit_logid_timestamp unit_logid_timestamp 14 const,const 4150932 100.00 Using where
1 SIMPLE validity ref unit_logid_timestamp unit_logid_timestamp 14 const,const 3294136 100.00 Using where
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE basepositions const PRIMARY,lat_lon,lat,lon PRIMARY 4 const 1 100.00
1 SIMPLE logdata ref unit_logid_timestamp unit_logid_timestamp 14 const,const 4150932 100.00 Using where
1 SIMPLE validity ref unit_logid_timestamp unit_logid_timestamp 14 const,const 3294136 100.00 Using where