2017-07-18 10 views
0

統計情報を格納するテーブルがあります。現時点では、1日の終わりに約1,000万行が移入され、毎日の統計表にコピーされて削除されます。このため、私は自動インクリメントの主キーを持つことはできません。このDBテーブルの最適なインデックスは何ですか?

これは、テーブルの構造である:

CREATE TABLE `stats` (
`shop_id` int(11) NOT NULL, 
`title` varchar(255) CHARACTER SET latin1 NOT NULL, 
`created` datetime NOT NULL, 
`mobile` tinyint(1) NOT NULL DEFAULT '0', 
`click` tinyint(1) NOT NULL DEFAULT '0', 
`conversion` tinyint(1) NOT NULL DEFAULT '0', 
`ip` varchar(20) CHARACTER SET latin1 NOT NULL, 
KEY `shop_id` (`shop_id`,`created`,`ip`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

私はshop_id, created, ipのキーを持っていますが、私はそれ以上の検索速度を向上させるために最適なインデックスを作成するために使用すべきかの列わからないんだけど?その上の結果の小さなセットを返すとなる最初の列を、あなたのWHERE句で

SELECT DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')) AS `date`, COUNT(*) AS `views` 
FROM `stats` 
WHERE `created` <= '2017-07-18 09:59:59' 
AND `shop_id` = '17515021' 
AND `click` != 1 
AND `conversion` != 1 
GROUP BY DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')) 
ORDER BY DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')); 
+0

次に、where句にshop_idを作成してからクリックするなどしています。 同じ順序でインデックスを作成します。 – money

+0

KEY created_shopid_click_conversion(作成、ショップID、クリック、コンバージョン); – money

答えて

1
  • 何列(または列の組み合わせ)が存在しない場合は、AUTO_INCREMENT idを持っています。切り詰め/削除について心配しないでください。 (ただし、IDがリセットされない場合は、オーバーフローを避けるためBIGINTを使用する必要があります(INT UNSIGNEDでは使用できません)。
  • PRIMARY KEY(shop_id, created, id), INDEX(id)の代わりにidをプライマリキーとして使用しないでください。
  • この非従来的なPKは、(idが追加されたために)ユニークである一方、2通りの方法でパフォーマンスに役立ちます。 INDEX(id)AUTO_INCREMENTを満足させることです。 (DELETE毎時または毎日は別問題です。)
  • 各時間(または分)に基づいてサマリーテーブルを作成します。これには、 - 400K /時間または7K /分のカウントが含まれます。 1時間(または分)ごとにそれを増やして、1日の終わりにすべての作業を行う必要はありません。
  • サマリーテーブルは、クリックやコンバージョンでフィルタリングすることもできます。 または必要な場合は両方を保持できます。
  • クリック/コンバージョンに2つの状態(0 & 1)しかない場合は、と言うわけではありません。オプティマイザは!=よりもはるかに良い=です。
  • 2ステートで=に変更した場合、これは実行可能になり、はるかに良好になります。INDEX(shop_id, click, conversion, created) - createdは最後にする必要があります。
  • Summaryテーブルに要約するときにTZを気にしないでください。後で変換を適用します。
  • さらに、DATETIMEは使用しないでください。TIMESTAMPを使用すると、(TZが正しく設定されていると仮定して)変換する必要はありません。

それでも問題が解決しない場合は、質問をやり直してください。さらに微調整があるかもしれません。

-1

使用します。

問合せは、下記より上のインデックスを使用していないキーを使用して、約12秒から約1.5秒かかりますインデックスを同じ順序で作成します。
他の3列と比較して作成したが、設定の小さな数を返します場合は、あなたが良いです
WHERE created <= '2017-07-18 09:59:59' AND shop_id = '17515021' AND click != 1 AND conversion != 1

を持っているそうでなければ、その列あなたのwhere句の最初の位置で、同じあたりのように、第2の列を選択説明とwhere句ごとにインデックスを作成します。
ご注文が問題ないと思われる場合は、

KEY created_shopid_click_conversion (created,shop_id, click, conversion);を作成してください。その後、を行うユニークな保証され

+0

WHEREの順序は問題ではありません。 'KEY' _の順序は重要です。また、範囲(「作成済み」)は、(まれな例外を除いて)インデックス内で最初になるべきではありません。 –

関連する問題