sql >> データベース >  >> RDS >> Mysql

mysql:SETまたは多くの列を使用しますか?

    主にパフォーマンスに関心があるようです。

    いくつかの人々が3つのテーブル(カテゴリテーブルと単純な相互参照テーブル、またはネストされたセットやマテリアライズドパスなどのツリー階層をモデル化するより洗練された方法)に分割することを提案しました。これは私があなたの質問を読んだときに最初に思ったものです。

    インデックスを使用すると、そのような完全に正規化されたアプローチ(2つのJOINを追加する)でも「かなり良い」読み取りパフォーマンスが得られます。 1つの問題は、イベントへのINSERTまたはUPDATEに、相互参照テーブルへの1つ以上のINSERT / UPDATE / DELETEが含まれる場合があることです。これは、MyISAMでは相互参照テーブルがロックされ、InnoDBでは行がロックされることを意味します。したがって、データベースが大量の書き込みでビジー状態の場合、イベント行だけがロックされている場合よりも大きな競合の問題が発生します。

    個人的には、最適化する前に、この完全に正規化されたアプローチを試してみます。しかし、私はあなたがあなたが何をしているのかを知っていると仮定します、あなたの仮定は正しい(カテゴリーは決して変わらない)そしてあなたはあまり正規化されていないフラットな構造を必要とする使用パターン(たくさんの書き込み)を持っています。これはまったく問題なく、NoSQLの一部です。

    SETと「たくさんの列」

    つまり、実際の質問「SETと多数の列」については、スマートエンジニア(製品はCRMWebアプリケーションでした...1つは実際にはイベント管理でした)を持つ2つの会社と協力したと言えます。この種の静的セットデータには「多数の列」アプローチを使用しました。

    私のアドバイスは、このテーブルで実行するすべてのクエリ(頻度で重み付け)と、インデックスがどのように機能するかを考えることです。

    まず、「多数の列」アプローチでは、SELECT FROM events WHERE CategoryX = TRUEを実行できるように、これらの各列にインデックスが必要になります。 。インデックスを使用すると、これは超高速のクエリです。

    SETの場合とは異なり、このクエリを実行するには、ビット単位のAND(&)、LIKE、またはFIND_IN_SET()を使用する必要があります。つまり、クエリはインデックスを使用できず、すべての行の線形検索を実行する必要があります(EXPLAINを使用してこれを確認できます)。遅いクエリ!

    これがSETが悪い考えである主な理由です。そのインデックスは、カテゴリの正確なグループで選択している場合にのみ役立ちます。 SETは、イベントごとにカテゴリを選択する場合に最適ですが、その逆はできません。

    正規化されていない「多数の列」アプローチの主な問題は(完全に正規化されているのではなく)、スケーリングされないことです。 5つのカテゴリがあり、それらが変更されない場合は問題ありませんが、500があり、それらを変更する場合、それは大きな問題です。シナリオでは、約30が変更されないため、主な問題はすべての列にインデックスがあることです。したがって、頻繁に書き込みを行う場合、更新する必要のあるインデックスの数が原因で、これらのクエリの速度が低下します。このアプローチを選択する場合は、MySQLの低速クエリログをチェックして、忙しい時間帯の競合が原因で異常値の低速クエリがないことを確認することをお勧めします。

    あなたの場合、あなたが典型的な読み取りの多いWebアプリである場合、(同じ理由で2つのCRM製品が行ったように)「大量の列」アプローチを採用することはおそらく正気だと思います。 間違いなく そのSELECTクエリのSETよりも高速です。

    TL; DR 「カテゴリでイベントを選択」クエリは遅くなるため、SETは使用しないでください。



    1. タイムトラッカーからカレンダーまでの時間を日ごとに合計する

    2. T-SQLを使用してSQLServerでユーザー定義のデータ型エイリアスを作成する方法

    3. MicrosoftSQLシーケンスとの数値の競合を回避する

    4. オプションを使用してコマンドラインから.sqlファイルをエクスポートおよびインポートする方法は?