1

研究プロジェクトのログファイルを評価し、MySQLデータベースに挿入しています。これで、完全に一致する値を持たずに他のテーブルのデータを結合する必要があるクエリがあります。

「logdata」テーブルには、分析する必要のあるモバイルユニットのデータが含まれています。「basepositions」には、基地局のGPS座標が含まれています。「logdata」の2つのデータフィールドには、対応する基地局の送信者の位置が記録されます。問題は次のとおりです。基地局の位置は時間の経過とともにわずかに変化するため(GPSの変動、わずか数度)、以下のクエリに示すように、BETWEEN操作を使用して正しいエントリを探す必要があります。これは完璧ではありませんが、基地局は約100しかないため、ここではコストは許容範囲内です。

同じ問題が2番目の結合にも存在します。そこで、別のテーブルから有効性フラグを取得する必要があります。ここでの問題は、両方のログがほぼ毎秒書き込まれますが、同期されていないことです。したがって、BETWEENと1秒の時間範囲を使用して、対応する行をスキャンする必要があります。

行数が多いため、この2回目のスキャンで実行時間が爆発的に増加します。ここで問題になるのは拡散相関だと思います。

2つのテーブルには、両方とも以下の概要に示されているインデックスがあります。

クエリを高速化する方法はありますか?パフォーマンスの問題のため、データベースのセットアップが完了して約20000行が返されるまでに30時間かかります。

助けていただければ幸いです。

logdata(〜300.000.000エントリ):

+-----------+---------------------+------+-----+---------+----------------+
| Field     | Type                | Null | Key | Default | Extra          |
+-----------+---------------------+------+-----+---------+----------------+
| id        | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| unit      | tinytext            | YES  | MUL | NULL    |                |
| timestamp | bigint(20)          | YES  |     | NULL    |                |
| logid     | int(11)             | YES  |     | NULL    |                |
| d1        | bigint(20)          | YES  |     | NULL    |                |
| d2        | bigint(20)          | YES  |     | NULL    |                |
| d3        | bigint(20)          | YES  |     | NULL    |                |
| d4        | bigint(20)          | YES  |     | NULL    |                |
| d5        | bigint(20)          | YES  |     | NULL    |                |
| d6        | bigint(20)          | YES  |     | NULL    |                |
| d7        | bigint(20)          | YES  |     | NULL    |                |
| d8        | bigint(20)          | YES  |     | NULL    |                |
| d9        | bigint(20)          | YES  |     | NULL    |                |
| d10       | bigint(20)          | YES  |     | NULL    |                |
+-----------+---------------------+------+-----+---------+----------------+

ベースポジション(〜100エントリ):

+----------------------------+--------------+------+-----+---------+-------+
| Field                      | Type         | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+-------+
| ID                         | int(11)      | NO   | PRI | NULL    |       |
| GPSLONGITUDE               | varchar(50)  | YES  |     | NULL    |       |
| LOCATION                   | varchar(100) | YES  |     | NULL    |       |
| GPSLATITUDE                | varchar(50)  | YES  |     | NULL    |       |
| GPSALTITUDE                | varchar(50)  | YES  |     | NULL    |       |
| ISUNDERTEST                | tinyint(1)   | YES  |     | 0       |       |
+----------------------------+--------------+------+-----+---------+-------+

有効性(〜200.000.000エントリ):

+-----------+---------------------+------+-----+---------+----------------+
| Field     | Type                | Null | Key | Default | Extra          |
+-----------+---------------------+------+-----+---------+----------------+
| id        | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| unit      | tinytext            | YES  | MUL | NULL    |                |
| timestamp | bigint(20)          | YES  |     | NULL    |                |
| logid     | int(11)             | YES  |     | NULL    |                |
| d1        | bigint(20)          | YES  |     | NULL    |                |
+-----------+---------------------+------+-----+---------+----------------+

これまでの私の質問:

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;

indeces:

+-------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 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は、クエリオプティマイザが3つのテーブルすべてを結合していることを示しています。これは、300.000.000 * 200.000.000*100行を調べることを意味します。「validity」を使用した結合をサブクエリに書き換えると、mysqlは「logdata」と「basepositions」を結合しているだけです。データ型の変更は、後で最適化する際の要因になる可能性があると思いますが、最初に、クエリプランを最適化していくつかのランタイムクラスを取得する必要があると思います。このクエリをさらに最適化するために何ができるかを知るのに十分な経験がありません。「有効性」に関するタイムスタンプの単一のクエリは、すぐに返されます。基地局の位置の単一のクエリも非常に高速です。私はしません

編集2:

これがあなたが求めたidexesです。「SHOWINDEXESFROM」を使って入手しました

「有効性」のインデックス:

+-------------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 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      |         |               |
+-------------------------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

「basepositions」のインデックス:

+----------------------+------------+---------------------------------------+--------------+----------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 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

EXPLAIN(lat / lonのインデックスを追加した後):

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
4

0 に答える 0