-1

私のクエリは 30 分以上実行されています。インデックスも含まれていても単純なクエリです。なぜ実行時間がかかりすぎていたのかを見つけることができず、データベース全体のパフォーマンスに影響を与えています。昨日実行しました: 122.6 分 誰でもここで私を助けることができます。クエリのパフォーマンスを向上させる方法

This is my query:
SELECT tab1.customer_id,tab1.row_mod,tab1.row_create,tab1.event_id,tab1.event_type,
tab1.new_value,tab1.old_value FROM tab1 force index (tab1_n2)where customer_id >= 1 and customer_id
< 5000000  and  (tab1.row_mod >= '2012-10-01') or  (tab1.row_create >=  '2012-10-01'  and tab1.row_create <  '2012-10-13');

Explain plan

+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
| id | select_type | table            | type | possible_keys       | key  | key_len | ref  | rows     | Extra       |
+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
|  1 | SIMPLE      | tab1 | ALL  | tab1_n2 | NULL | NULL    | NULL | 18490530 | Using where |
+----+-------------+------------------+------+---------------------+------+---------+------+----------+-------------+
1 row in set (0.00 sec)

Table structure:

mysql> show create table tab1\G
*************************** 1. row ***************************
       Table: tab1
Create Table: CREATE TABLE `tab1` (
  `customer_id` int(11) NOT NULL,
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `event_id` int(11) DEFAULT NULL,
  `event_type` varchar(45) DEFAULT NULL,
  `new_value` varchar(255) DEFAULT NULL,
  `old_value` varchar(255) DEFAULT NULL,
  KEY `customer_id1` (`customer_id`),
  KEY `new_value_n1` (`new_value`),
  KEY `tab1_n1` (`row_create`),
  KEY `tab1_n2` (`row_mod`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

インデックスを持っていても、調整する方法を教えてください

4

2 に答える 2

0

2 つの条件の UNION を使用してみてください。そうすれば、各条件でインデックスを使用できます。

ALTER TABLE tab1 ADD INDEX idx_row_mod_customer_id (row_mod, customer_id);

ALTER TABLE tab1 ADD INDEX idx_row_create (row_create);

SELECT tab1.customer_id, tab1.row_mod, tab1.row_create, tab1.event_id, tab1.event_type,
tab1.new_value, tab1.old_value
FROM tab1
WHERE customer_id >= 1 and customer_id
< 5000000 AND tab1.row_mod >= '2012-10-01'

UNION

SELECT tab1.customer_id, tab1.row_mod, tab1.row_create, tab1.event_id, tab1.event_type,
tab1.new_value, tab1.old_value
FROM tab1
WHERE tab1.row_create >= '2012-10-01' AND tab1.row_create <  '2012-10-13';

さらに最適化するには、選択したすべての列を両方のインデックスに追加して、MySQL が行をメモリにロードする必要がないようにします。これにより、インデックスのサイズが大幅に増加するため、必要なメモリが増加します。

于 2013-10-30T05:33:49.977 に答える
0

おそらく、意味のないインデックスを使用しているためです。

row_mod 条件は OR 条件の分岐の 1 つにすぎないため、ここでは index はあまり役に立ちません。行を削除せずにインデックスを介してすべてのルックアップを強制すると、テーブル全体のスキャンよりもはるかに遅くなる可能性があります。経験則として、インデックスは 90% 以上の行を削除する必要があります。

「強制インデックス」部分なしで実行してみてください。

于 2012-12-27T05:09:05.010 に答える