4

約 2,000 万行のデータを含む MySQL テーブルがあります。

+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| b_id        | int(11)     | YES  | MUL | NULL    |                |
| order       | bigint(20)  | YES  | MUL | NULL    |                |
| date        | date        | YES  |     | NULL    |                |
| time        | time        | YES  |     | NULL    |                |
| channel     | varchar(8)  | YES  | MUL | NULL    |                |
| data        | varchar(60) | YES  |     | NULL    |                |
| date_system | date        | YES  | MUL | NULL    |                |
| time_system | time        | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+

次のようなクエリを高速化するために、(b_id、channel、date) に一意でないインデックスがありました。

select date, left(time,2) as hour, round(data,1) as data
from data_lines
where channel='1'
  and b_id='300'
  and date >='2013-04-19'
  and date <='2013-04-26' 
group by date,hour

問題は、挿入が重複することがあるため、「ON DUPLICATE KEY UPDATE」を使用したかったのですが、これには一意のインデックスが必要です。したがって、(b_id、チャネル、日付​​、時刻) に一意のインデックスを作成します。これは、double 値があるかどうかを判断するための 4 つの主要な特性であるためです。挿入は正常に機能するようになりましたが、選択クエリは許容できないほど遅くなります。

新しいインデックスが追加されてから、選択が遅くなった理由はよくわかりません。

  • 時間は非常にユニークであるため、インデックスが非常に大きくなります --> そして遅くなりますか?
  • 高速化するために非一意のインデックスを削除する必要がありますか?
  • それは私の悪いクエリですか?
  • 他のアイデアを歓迎します!

レコード (order、date_system、および time_system) は、インデックスまたは選択ではまったく使用されませんが、データが含まれています。挿入は C と Python から実行され、選択は PHP から実行されます。

要求ごとに説明クエリ:

mysql> explain select date, left(time,2) as hour, round(data,1) as data 
from data_lines 
where channel='1'
  and b_id='300'
  and date >='2013-04-19'
  and date <='2013-04-26'
group by date,hour;

+----+-------------+-----------+------+--------------------------------+------------+---------+-------------+------+----------------------------------------------+
| id | select_type | table     | type | possible_keys                  | key        | key_len | ref         | rows | Extra                                        |
+----+-------------+-----------+------+--------------------------------+------------+---------+-------------+------+----------------------------------------------+
|  1 | SIMPLE      | data_lines| ref  | update_index,b_id,comp_index   | comp_index | 16      | const,const | 3548 | Using where; Using temporary; Using filesort |
+----+-------------+-----------+------+--------------------------------+------------+---------+-------------+------+----------------------------------------------+

update_index は (b_id, channel, date, time) の一意のインデックスであり、comp_index は (b_id, channel, date) の一意でないインデックスです。

インデックスは次のとおりです。

+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| data_lines|          0 | PRIMARY      |            1 | id          | A         |    17918898 |     NULL | NULL   |      | BTREE      |         |               |
| data_lines|          0 | id_UNIQUE    |            1 | id          | A         |    17918898 |     NULL | NULL   |      | BTREE      |         |               |
| data_lines|          0 | update_index |            1 | channel     | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          0 | update_index |            2 | b_id        | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          0 | update_index |            3 | date        | A         |       44244 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          0 | update_index |            4 | time        | A         |    17918898 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | box_id       |            1 | b_id        | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | idx          |            1 | order       | A         |    17918898 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | comp_index   |            1 | b_id        | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | comp_index   |            2 | channel     | A         |        6624 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | comp_index   |            3 | date        | A         |      165915 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | date_system  |            1 | date_system | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| data_lines|          1 | mac          |            1 | mac         | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4

2 に答える 2

3

USE INDEX(update_index)クエリで明示的に指定してみてください。

オプティマイザーがインデックスの選択で間違った選択をしているため、クエリが遅くなります。

これで問題が解決することを願っています.. :)

于 2013-04-26T07:46:04.527 に答える