2

volkszaehler.org を使用して、100 万行以上のテーブルからデータを取得する必要があります。以下は、ORM が作成するものです。

CREATE TABLE `data` (
  `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_ADF3F36372F5A1AA` (`channel_id`)
)

現在、特に Raspberry Pi のような低パフォーマンスのプラットフォームで実行すると、グループ化されたデータの選択が遅くなります。

SELECT MAX(timestamp) AS timestamp, SUM(value) AS value, COUNT(timestamp) AS count 
FROM data WHERE channel_id = 4 AND timestamp >= 1356994800000 AND timestamp <= 1375009341000 
GROUP BY YEAR(FROM_UNIXTIME(timestamp/1000)), DAYOFYEAR(FROM_UNIXTIME(timestamp/1000));

説明:

SIMPLE  data    ref ts_uniq,IDX_ADF3F36372F5A1AA    ts_uniq 5   const   2066    Using where; Using temporary; Using filesort

クエリは 50,000 レコードを処理する必要があり、Core i5 では 1.5 秒、RasPi ではすでに 6 秒かかります。

データ量の削減以外にパフォーマンスを改善する方法はありますか?

4

1 に答える 1

1

データ量を減らすのではなく、増やすことが必要です。GROUP BY 句に 2 つの関数があり、これを計算YEAR(FROM_UNIXTIME(timestamp/1000))してDAYOFYEAR(FROM_UNIXTIME(timestamp/1000))事前にトリガーで値を追加フィールドに保存すると、SELECT ステートメントがはるかに高速になります。

それ以外は、timestamp1000*3600*24=86400000 で割り、1 つのフィールドのみでグループ化することにより、単純に最も近い日に切り捨てることができます。日付のみでグループ化:

SELECT 
 MAX(timestamp) AS timestamp, 
 SUM(value) AS value, 
 COUNT(timestamp) AS count 
FROM data WHERE 
 channel_id = 4 AND 
 timestamp >= 1356994800000 AND 
 timestamp <= 1375009341000 
GROUP BY timestamp/86400000;

個人的には、その後、日付フィールドを追加してインデックスを作成し、トリガーで更新して、GROUP BY からすべての算術式を削除できるようにします。その場合、インデックスが使用されます。

于 2013-07-28T11:36:18.577 に答える