6

すべて検索可能な20以上の列を持つテーブルを持つアプリケーションがあります。これらすべての列のインデックスを作成すると、書き込みクエリが非常に遅くなります。また、実際に役立つインデックスは、多くの場合、複数の列にまたがる必要があり、必要なインデックスの数が増えます。

ただし、これらの検索の95%については、これらの行のごく一部のみを検索する必要があり、非常に少数(たとえば、50,000行)です。

そのため、mySQLパーティションテーブルの使用を検討しました。基本的isActiveに、2つのパーティションを分割する列があります。ほとんどの検索クエリは。で実行されisActive=1ます。その場合、ほとんどのクエリは50,000行の小さなパーティションに対して実行され、他のインデックスがなくても迅速に実行されます。

唯一の問題は、isActive=1修正されていない行です。つまり、行の日付やそのように修正されたものに基づいていません。isActiveその行のデータの使用に基づいて更新する必要があります。私が理解しているように、それは問題ではありません。データは、UPDATEクエリ中に1つのパーティションから別のパーティションに移動されるだけです。

しかし、私たちはPKそのid列に賛成です。これが問題かどうかはわかりません。マニュアルは、パーティションが主キーに基づいている必要があることを示唆しているように見えました。主キーIDには行かどうかの根拠がないため、これは私たちにとって大きな問題になりますisActive

4

4 に答える 4

7

私はMySQLの専門家ではありません。私の焦点はOracleですが、Partitioningを何年も使用しており、提案された使用法は非常に適切であるが、パーティションの主流の理解の範囲内ではないことがわかりました。

カーディナリティの低い列のインデックス

今のところ、インデックスのマージは脇に置いておきます。アクティブな行がいくらか分散していて、非アクティブな行の数と1:20の比率であるとしましょう。ページサイズが8Kbで、ブロックあたり約20行になるとします。isactiveレコードが非常に均等に分布している場合は、ブロックごとにほぼ1つになります。全表スキャンは、インデックスを使用して同じ行を見つけるよりも、テーブル内のすべてのブロック/ページを読み取る方がはるかに高速です。

それで、それらが均等に散らばっているのではなく、集中しているとしましょう。それらがページの20%またはページの10%にさえ集中している場合でも、そのような場合でも、全表スキャンはインデックスを実行できません。

したがって、インデックスのマージを含めます。ISactiveのインデックスをスキャンした後、テーブルにアクセスせずに、それらの結果を別のインデックスの結果に結合すると、その最終結果セットは、たとえば、ブロックの5%未満の読み取り値を生成します。そうすれば、isactiveのインデックスとインデックスのマージが解決策になる可能性があります。

ここでの注意点は、MySQLでのインデックス結合の実装には多くの制限があるということです。これがあなたの状況で機能することを確認してください。しかし、あなたは検索されるかもしれない別の20のフィールドがあると言いました。したがって、それらすべてにインデックスを付けず、IsActiveインデックスを結合するために使用可能な2番目のインデックスがある場合は、インデックスのマージ/結合を使用しません。

低カーディナリティ列の分割

これで、その列でパーティションを作成すると、IsActive = Trueのブロックの5%が含まれ、密集してパックされます。フルパーティションスキャンは、アクティブなレコードのリストをすばやく生成し、他のすべての述部をインデックスシークの代わりにフィルターとして適用できるようにします。

しかし、そのフラグは変わります。

Oracleには、行の移行を有効にするコマンドがあります。つまり、Is_ActiveがTrueからFalseに変更されたら、行が含まれるパーティションを移動します。これはかなりコストがかかりますが、パーティション化する代わりにその列にインデックスを付けた場合に発生するインデックスのメンテナンスよりも少しだけ高くなります。パーティション化された例では。Oracleは、最初に更新を使用して行を変更し、次に削除を実行してから挿入を実行します。その列にインデックスを付けた場合、行を更新すると、TRUEのインデックスエントリが削除され、Falseのインデックスエントリが作成されます。

MySQLに行の移行がない場合は、それを行うためにcrudパッケージをプログラムする必要があります。UPDATE_ROW_ISACTIVE(pk IN number)プロシージャ<----そのようなもの)が削除と挿入を行います。

コネラックの答えについて

並列アクセスはパーティショニングの1つの使用法であることに同意しますが、それは排他的なものではありません。しかし、彼が提供するリンクをたどると、ページの一番下にあるユーザーのコメントは次のようになります。

テーブルの選択性インデックスが低いことに注意してください。Index_Merge最適化がintersect()アルゴリズムで使用されている場合、複雑なAND / OR WHERE句を使用すると、クエリが非常に遅くなります。

それはあなたの状況を物語っているようです、それであなたはそのコメントをFWIWを取ることができます。

于 2011-01-06T17:31:10.320 に答える
1

その数の「列」にインデックスを付ける場合は、データ構造を再考することをお勧めします。たとえば、代わりに各列を行/レコードにします。次に、個々のレコードをリンクするための「グループID」と、それがどのデータであるかを示す「名前」フィールドを用意します。次に、すべてのデータに対して1つのインデックスのみが必要です。

この名前/値ペアの設定は、実際には現在かなり一般的であり、一部のnoSQLデータベースが基づいているものです。これはあなたが調べたいと思うかもしれない何か他のものです。MongoDBのようなものは、「すべての」データのインデックス作成に最適です。

于 2011-01-08T15:10:05.360 に答える
0

このためにパーティションは必要ありませんisActive。列のインデックスだけで十分です。MySQLはインデックスマージ操作を使用して両方のインデックスを使用できることに注意してください。

パーティションは、検索を並行して実行できる場合に役立ちます。たとえば、日付ごとにパーティションを作成する場合、5つのパーティションを同時に検索して、5年間にわたる結果を見つけることができます。

于 2010-12-13T13:25:54.440 に答える
-1

「テーブル」と「データベース」の説明は、正規化の欠如の典型的な症状です。20個の検索可能な列を持つ「テーブル」は3NFではなく、おそらく1NFでもありません。最善のアドバイスは、最初の原則に戻ってデータを正規化することです。これにより、テーブルがはるかに狭くなり、テーブルあたりの行数も少なくなりますが、確かにモートテーブルになります。ただし、結果には、テーブルごと、および全体として、インデックスも少なくなります。

そして、はるかに高速なデータベース。脂肪全体の「テーブル」は、あらゆるレベルでパフォーマンスを損なうものです。

ここではパーティションは適用されません。問題を緩和することはできません。

idPKは、追加の列インデックス、代理、実際の主キーの代替(ただし、代替ではない)です。リレーショナルモデリング手法を使用した場合、それを排除することができ、少なくとも19の検索可能なインデックスになります。「テーブル」での深刻な作業は、たとえば、パーティションの制限からわかるように、サロゲートではなく、実際のP​​Kを中心に行われます。

それについて話し合いたい場合は、「テーブル」と接続されているすべての「テーブル」のDDLを投稿してください。

コメントへの回答

このテーブルは「電子メール」と考えるのが最適ですが、すべて適切に正規化された多くの追加フィールド(カテゴリ/部門/優先度/ワークフロー/所有者)があります。非常に多くのタイムスタンプを含む、他のさまざまな変数もあります。

これが、 0NFでのフラットファイルの定義そのものです。「正規化」の記述されていない定義を使用していない限り、それは、あなた自身の説明によれば、まったく正規化されていません。これは、正規化が開始される前に開始する記事です。

  • クエリに役立つように、インデックスもファットワイドになることは間違いありません。

  • まだ気付いていないかもしれませんが、そのファイルには大量のデータ重複があり、異常の更新(1つの行の列を更新する場合、他の行の重複した値を更新する必要があります)により、アプリケーションが不必要に複雑になります。

すべてのリレーショナルDBMSベンダーが、リレーショナルデータベースを処理するために最適化されたリレーショナルデータベースエンジンを作成いることを理解する必要があります。つまり、非正規化または非正規化ではなく、正規化された構造に最適化されています。

私は学術的な議論に引き込まれることはありません。SOは質疑応答サイトであり、討論サイトではありません。要求に応じて、ファイルと接続されているすべてのファイルのDDLを投稿すると、(a)速度を上げ、(b)20以上のインデックスを回避できます(これは、この状態のもう1つの一般的な症状です)。それは特定の現実世界の問題に対処し、それを解決し、議論を避けます。

第二に、あなたは役割が混同されているようです。問題を抱えているのはあなたであり、SOに質問を投稿し、何百ものパフォーマンスの問題を修正して答えたのは私です。定義上、ソリューションはドメイン外にあります。そうでない場合は、ソリューションを解決しているため、質問を投稿することはありません。そのため、問題の解決方法を教えても機能しません。それはあなたが持っているのと同じ制限に私を縛り付け、それで私が問題を解決しないことを確実にするでしょう。

また、テストから、WHERE句に含める必要のあるテーブルをJOINに追加すると、クエリが遅くなるだけです。

実際、私は生活のためにデータベースを調整しており、多くの小さなテーブルを結合する方が速いことを示す何百ものテストがあります。コーダーのテストとコーディング機能を調べるのは興味深いことですが、それでは議論が始まるので、そうしないでください。質問に固執しましょう。(a)真剣なテストの例が必要な場合は、(b)異議を申し立てる前に私が述べたことを証明します。これは、完全に文書化され、オラクルの世界の支持者を精査し、対応するテストを行っている 1つの例です。

あなたはまた、あなたが近づいている同じ議論を殺したこの質問/回答に興味があるかもしれません。

参加には費用はかかりません。参加するファイルいずれかの側で結合されたレコードの数。インデックスの有用性、つまりコストがかかる場所です。それが別の正規化されていないファイル(太い、幅の広い、多くのオプションの列)である場合は、遅くなることを確認してください。

とにかく、投稿された問題の修正に本当に興味がある場合は、すべてのDDLを投稿してください。そうすれば、より速く処理できます。必要なのがパーティションに関するyes/noの答えだけである場合(そして原因となる問題に対処しないため)、それも問題ありません。あなたはすでにそれを持っています。

于 2011-01-08T14:44:39.237 に答える