1

MySQLデータベースパーティショニングの実装がアプリケーションにとって有益かどうかを確認しようとしていました。多数のレコードにパーティショニングを使用することの利点について多くのことを聞きました。しかし、驚くべきことに、パーティショニングの実装後に負荷テストを実行すると、アプリケーションの応答時間が3分の1に短縮されました。誰かがこれが起こるかもしれない理由を手伝ってもらえますか?

詳細に説明させてください。

以下は、パーティショニングが「行われなかった」場合のテーブルのDDLです。

CREATE TABLE `myTable` ( 
`column1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
`column2` char(3) NOT NULL, 
`column3` char(3) NOT NULL, 
`column4` char(2) NOT NULL, 
`column5` smallint(4) unsigned NOT NULL, 
`column6` date NOT NULL, 
`column7` varchar(2) NOT NULL, 
`column8` tinyint(3) unsigned NOT NULL COMMENT 'Seat Count Ranges from 0-9.', 
`column9` varchar(2) NOT NULL, 
`column10` varchar(4) NOT NULL, 
`column11` char(2) NOT NULL, 
`column12` datetime NOT NULL, 
`column13` datetime DEFAULT NULL, 
PRIMARY KEY (`column1`), 
KEY `index1` (`column2`,`column3`,`column4`,`column5`,`column7`,`column6`), 
KEY `index2` (`column2`,`column3`,`column6`,`column4`) 
) ENGINE=InnoDB AUTO_INCREMENT=342024674 DEFAULT CHARSET=latin1; 

以下は、日付フィールドに基づいて「範囲」パーティショニングを実装した後の同じテーブルのDDLです。

CREATE TABLE `myTable` ( 
`column1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
`column2` char(3) NOT NULL, 
`column3` char(3) NOT NULL, 
`column4` char(2) NOT NULL, 
`column5` smallint(4) unsigned NOT NULL, 
`column6` date NOT NULL, 
`column7` varchar(2) NOT NULL, 
`column8` tinyint(3) unsigned NOT NULL COMMENT 'Seat Count Ranges from 0-9.', 
`column9` varchar(2) NOT NULL, 
`column10` varchar(4) NOT NULL, 
`column11` char(2) NOT NULL, 
`column12` datetime NOT NULL, 
`column13` datetime DEFAULT NULL, 
PRIMARY KEY (`column1`,`column6`), 
KEY `index1` (`column2`,`column3`,`column4`,`column5`,`column7`,`column6`), 
KEY `index2` (`column2`,`column3`,`column6`,`column4`) 
) ENGINE=InnoDB AUTO_INCREMENT=342024674 DEFAULT CHARSET=latin1 
PARTITION BY RANGE COLUMNS(`column6`) 
(PARTITION date_jul_11 VALUES LESS THAN ('2011-08-01') ENGINE = InnoDB, 
PARTITION date_aug_11 VALUES LESS THAN ('2011-09-01') ENGINE = InnoDB, 
PARTITION date_sep_11 VALUES LESS THAN ('2011-10-01') ENGINE = InnoDB, 
PARTITION date_oct_11 VALUES LESS THAN ('2011-11-01') ENGINE = InnoDB, 
PARTITION date_nov_11 VALUES LESS THAN ('2011-12-01') ENGINE = InnoDB, 
PARTITION date_dec_11 VALUES LESS THAN ('2012-01-01') ENGINE = InnoDB, 
PARTITION date_jan_12 VALUES LESS THAN ('2012-02-01') ENGINE = InnoDB, 
PARTITION date_feb_12 VALUES LESS THAN ('2012-03-01') ENGINE = InnoDB, 
PARTITION date_mar_12 VALUES LESS THAN ('2012-04-01') ENGINE = InnoDB, 
PARTITION date_apr_12 VALUES LESS THAN ('2012-05-01') ENGINE = InnoDB, 
PARTITION date_may_12 VALUES LESS THAN ('2012-06-01') ENGINE = InnoDB, 
PARTITION date_jun_12 VALUES LESS THAN ('2012-07-01') ENGINE = InnoDB, 
PARTITION date_jul_12 VALUES LESS THAN ('2012-08-01') ENGINE = InnoDB, 
PARTITION date_aug_12 VALUES LESS THAN ('2012-09-01') ENGINE = InnoDB, 
PARTITION date_sep_12 VALUES LESS THAN ('2012-10-01') ENGINE = InnoDB, 
PARTITION date_oct_12 VALUES LESS THAN ('2012-11-01') ENGINE = InnoDB, 
PARTITION date_nov_12 VALUES LESS THAN ('2012-12-01') ENGINE = InnoDB, 
PARTITION date_dec_12 VALUES LESS THAN ('2013-01-01') ENGINE = InnoDB, 
PARTITION date_jan_13 VALUES LESS THAN ('2013-02-01') ENGINE = InnoDB, 
PARTITION date_feb_13 VALUES LESS THAN ('2013-03-01') ENGINE = InnoDB, 
PARTITION date_mar_13 VALUES LESS THAN ('2013-04-01') ENGINE = InnoDB, 
PARTITION date_apr_13 VALUES LESS THAN ('2013-05-01') ENGINE = InnoDB, 
PARTITION date_may_13 VALUES LESS THAN ('2013-06-01') ENGINE = InnoDB, 
PARTITION date_jun_13 VALUES LESS THAN ('2013-07-01') ENGINE = InnoDB, 
PARTITION date_oth VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB); 

以下は、パフォーマンスをテストするための負荷テストを実行するために使用されたサンプルクエリです。

SELECT column8, column9
FROM myTable
WHERE column2 = ? AND column3 = ? AND column4 =? AND column5 = ? AND column7 = ? AND column6 = ?
LIMIT 1 

上記?は、テスト用にデータベースに存在する実際の値に置き換えられました。

'myTable'テーブルのレコード数は約3億4200万であり、パフォーマンステストの実行に使用されるテストデータの数は約200万であることに注意してください。

しかし、私が言ったように、パーティショニングを実装した後のパフォーマンスは、衝撃的な3倍に低下しました。これを引き起こした可能性のあるアイデアはありますか?

また、テーブル構造またはインデックス作成をさらに変更すると、この問題の解決に役立つ場合があるかどうかをお知らせください。

4

2 に答える 2

1

パーティショニングの目標は、クエリが結果を見つけることができるパーティションの数を制限するクエリを高速化することです。問題はcolumn6 = ?テストクエリにあると思います。column6 に範囲ではなく正確な値を要求すると、結果セットが非常に少ない値になると思います。したがって、パーティションを絞り込む過程で、本質的にはすでに結果を見つけています。また、インデックスは複数のパーティションに分割されるため、その縮小プロセスにはコストがかかります。

column6 でパーティション化することでメリットが期待できる種類のクエリは、少数のパーティションに限定された値の範囲を返すものです。たとえば、テスト クエリとして次のようなものを試してください。

SELECT column8, column9
FROM myTable
WHERE column6 < ? AND column6 > ? AND column2 = ? AND column3 = ? AND column4 =? AND column5 = ?

ここで、その column6 の範囲は約 2 つのパーティションにまたがり、結果の総数はかなり大きくなると予想されます。

これは役立つかもしれません: http://dev.mysql.com/tech-resources/articles/partitioning.html

于 2013-02-19T06:19:11.523 に答える
0

これを見ると、いろいろと考えさせられます。

最初の、そして最も明白な問題は、データをさまざまなデバイス (ディスク) に分散させると、パーティショニングの大きな利点が得られるということです。投稿されたコードからは、その証拠はありません。

次に、パーティショニングは特定の日付範囲にハードコードされているため、date_oth がいっぱいになり始めたときに、より良い計画を立てる必要があります。

AND column6 = ?

では、単一のパーティションからのデータのパフォーマンスのみをテストしましたか? せいぜい、これは 1 つのテーブルにすべてのデータがある場合よりも高速ではありません。

Nathan が指摘しているように、列 6 でパーティション分割していますが、これはどのインデックスの前にもありません。したがって、DBMS は各パーティションのインデックスを検索してデータを見つける必要があります。パフォーマンスがとても悪いです。(パーティショニングは範囲クエリのみに役立つことに同意しません)。

于 2013-05-29T13:23:28.400 に答える