〜9mのレコードを持つInnoDBテーブルが大きくて狭いです。テーブルでcount(*)
またはcount(id)
を実行すると、非常に遅くなります(6秒以上):
_DROP TABLE IF EXISTS `perf2`;
CREATE TABLE `perf2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`channel_id` int(11) DEFAULT NULL,
`timestamp` bigint(20) NOT NULL,
`value` double NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ts_uniq` (`channel_id`,`timestamp`),
KEY `IDX_CHANNEL_ID` (`channel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
RESET QUERY CACHE;
SELECT COUNT(*) FROM perf2;
_
ステートメントはあまり頻繁に実行されませんが、最適化するのは良いことです。 http://www.cloudspace.com/blog/2009/08/06/fast-mysql-innodb-count-really-fast/ によると、これはInnoDBにインデックスの使用を強制することで可能になります。 :
_SELECT COUNT(id) FROM perf2 USE INDEX (PRIMARY);
_
EXPLAIN PLANは問題ないようです。
_id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE perf2 index NULL PRIMARY 4 NULL 8906459 Using index
_
残念ながら、声明は以前と同じくらい遅いです。 "SELECT COUNT(*)"は、where句がある場合でも遅い によると、成功せずにテーブルの最適化も試みました。
InnoDBでCOUNT(*)
パフォーマンスを最適化する方法は何ですか?
当分の間、私はこの近似を使用して問題を解決しました:
EXPLAIN SELECT COUNT(id) FROM data USE INDEX (PRIMARY)
上記のようにInnoDBを使用する場合、おおよその行数は、Explain Planのrows
列から読み取ることができます。 MyISAMを使用する場合、テーブル参照が最適化されているため、これは空のままです。したがって、従来のSELECT COUNT
代わりに。
MySQL 5.1.6以降では、 Event Scheduler を使用して、統計テーブルに定期的にカウントを挿入できます。
最初に、カウントを保持するテーブルを作成します。
CREATE TABLE stats (
`key` varchar(50) NOT NULL PRIMARY KEY,
`value` varchar(100) NOT NULL);
次に、テーブルを更新するイベントを作成します。
CREATE EVENT update_stats
ON SCHEDULE
EVERY 5 MINUTE
DO
INSERT INTO stats (`key`, `value`)
VALUES ('data_count', (select count(id) from data))
ON DUPLICATE KEY UPDATE value=VALUES(value);
完璧ではありませんが、必要な新鮮さの数だけ実行するように簡単に調整できる自己完結型のソリューション(cronジョブまたはキューなし)を提供します。
@Cheコードに基づいて、statsテーブルの値を最新の状態に保つために、perf2へのINSERTおよびUPDATEでトリガーを使用することもできます。
CREATE TRIGGER `count_up` AFTER INSERT ON `perf2` FOR EACH ROW UPDATE `stats`
SET
`stats`.`value` = `stats`.`value` + 1
WHERE
`stats`.`key` = "perf2_count";
CREATE TRIGGER `count_down` AFTER DELETE ON `perf2` FOR EACH ROW UPDATE `stats`
SET
`stats`.`value` = `stats`.`value` - 1
WHERE
`stats`.`key` = "perf2_count";
これには、count(*)を実行するパフォーマンスの問題を排除できるという利点があり、テーブルのデータが変更されたときにのみ実行されますperf2