1

すべてのシステム ユーザーを保持するテーブルがあります。時間が経つにつれて、一部のユーザー アカウントは休眠状態になり、この表では使用されなくなります。

多数のユーザーがいる場合は、テーブルを日付 (最終ログオン日) で分割し、日付に基づいてユーザーをクエリするとよいでしょう。例: ログインすると、パーティショニングが使用する lastlogondate が更新されます。

質問: これは、日付スタンプが最新であるため、現在のすべてのユーザーが最初のパーティションにいることを意味しますか? これは、アクティブなユーザーの現在のプールを 1 つのパーティションに保持する良い方法であり、廃止されたアカウントのリセットは、最後のアクティブな日付に応じて他のパーティションに存在することになります。(注: ユーザーが再度ログインすると、再びアクティブになります)。

これはクエリを高速化する良い方法でしょうか?

4

1 に答える 1

3

いいえ、このパーティション分割方法は使用しません。

MySQLパーティションのプルーニングを利用するには、クエリでパーティションキーの列を参照する必要があります。したがって、提案されたパーティションスキームでメリットを得るには、ユーザーに対するすべてのクエリでlast_login列を参照する必要があり、last_login列と比較する値を継続的に更新する必要があります。

SELECT ... FROM users WHERE user_name = 'Adam' AND last_login >= '2013-01-01'
-- remember to change this to '2013-02-01' by next month

特定のlast_loginを検索するという用語がないと、クエリはすべてのパーティションをスキャンする必要があります。

また、「パーティションチャーン」、つまり行が1つのパーティションから別のパーティションに頻繁に移動することも心配です。

また、MySQLでは、パーティション列はテーブル内のすべての主キーまたは一意キーの一部である必要があることを思い出してください。したがって、last_loginをパーティションキーとして使用するには、テーブルを定義する必要があります。

CREATE TABLE Users (
  user_name VARCHAR(12) NOT NULL,
  last_login DATETIME NOT NULL,
  ...
  PRIMARY KEY (user_name, last_login)
);

これにより、最終ログイン時刻が明確である限り、アカウント「Adam」を作成している別のユーザーのデータ異常の可能性が広がります。2人のAdamがまったく同時にログインするまで、両方のアカウントが同じテーブルに無期限に存在する可能性があります。次に、主キー違反のためにログインが拒否される場合があります。これは、ログインが拒否される非常に不可解な理由になります。

少し良いパーティションスキームはこれです:

CREATE TABLE Users (
  user_name VARCHAR(12) NOT NULL,
  last_login DATETIME NOT NULL,
  is_archived TINYINT(1) NOT NULL DEFAULT 0,
  ...
  PRIMARY KEY (user_name, is_archived)
) PARTITION BY HASH(is_archived) PARTITIONS 2;

その目的は、定期的にジョブを実行してユーザーを手動でアーカイブすることです。

UPDATE Users SET is_archived=1 WHERE last_login < CURDATE() - INTERVAL 30 DAY;

これにより、パーティションチャーンの問題とパーティション作成の雑用の問題が解決されます。それでも潜在的に複数の「アダム」が存在する可能性がありますが、あるパーティションから別のパーティションに行を移動するインスタンスを注意深く制御すれば、リスクは低くなります。

クエリでパーティションキーを参照する必要がありますが、比較する値は修正されます。

SELECT ... FROM users WHERE user_name = 'Adam' AND is_archived = 0;
于 2013-01-07T23:28:26.183 に答える