2016-12-15 15 views
1

〜400KレコードのinnoDBテーブルを取得します。まれに(決して決して)更新されない場合。mysql - 多くの<テストでwhere節を最適化する

A =値(4から14の範囲の整数、インデックス付け、値) B =値:

最も頻繁な要求は、COUNT(*)句は論理的に、以下のようにいくつかの条件で構成される場合と、選択され

可変数のCx <値条件(0〜26条件) 各Cxはint型の列と一致し、0〜7の値をとります

Cx列は最初に索引付けされません。パフォーマンスに大きな影響を与えずにインデックスを作成しようとしました。

このクエリの最適化の考え方は歓迎します。

このクエリ自体を最適化しようとすること以外に、約25件の連続したリクエストが得られる状況では、2番目の最適化レベルにもあります。それぞれにはCx条件のセットが同じですが、Aそして

Cx条件のセットだけで一時テーブルを作成し、AとBの条件でその一時テーブルから選択することは有望だろうと思いますか?クエリをreforging、テーブルにフィールドを追加考える

------------------

UPDATE 1 ...私が持っていましたベンド、ボブ、リックのおかげで、私を基礎にしてくれたので、何らかの基礎を忘れてしまった。

A /このテーブルが更新されることはめったにありませんが、私はMyISAMのエンジンを変更しました。 オリジナルのinnoDBsizeの2/3までサイズを絞っただけでなく、これによりクエリのパフォーマンスが25%向上しました。

B/Iは、AインデックスとBインデックスのカーディナリティが低いと考えました。私の設定とBobの設定との間のかなりの違いを説明する事実に加えられました。 : A列とB列の値の分布はランダムではありません。それらは完全平均ガウス分布に近く、例えば平均-A = 10および標準-A = 1であり、人口の大多数がA = {9,10,11}を得て、関連付けられたインデックスを決定的に選択的にレンダリングしないことを示している。 Bについての観測はBと似ています。

Bは実際には単一の列ではなく、列B1、B2、B3、B4であると言われているため、4つの複合インデックス(A、Bi) 4.

だから、すべての5

を乗じた全ての公演で私は幸せに近いです! お寄せいただきありがとうございます。

+1

有用な(コンポジット)インデックスを作成し、クエリを最適化しますが、私はそれらを参照してください –

+0

26のコンポジットインデックス(A、B、c1)、(A、B、c2)または1つの複合インデックス(c1、c2、...、C26)? – aCOSwt

+0

1つの合成インデックスのみ。フィールドの秩序はインポテンツです。結果を減らすフィールドが最も最初でなければなりません –

答えて

1

私は、クエリの追加の最適化は必要ありません。それが遅い場合は、データベースの設定を確認する必要があります。あるいは、ハードウェアに問題があるかもしれません。 私は小さな仮想サーバ(1つのCPU、512M RAM)上のいくつかのテストだった。そして、

mysql> create table t (a int(1), b varchar(1), c1 int(1), c2 int(1), c3 int(1), c4 int(1)); 
    mysql> create index ia on t(a) ; 
    mysql> create index ib on t(b) ; 

を、私は

insert into t values 
(6, 'T', 4, 6, 3, 4), 
(12, 'z', 3, 5, 6, 1), 
... 

mysql> select count(*) from t where a=5 and b='x' and c1 > 5; 
+----------+ 
| count(*) | 
+----------+ 
|  340 | 
+----------+ 
1 row in set (0.04 sec) 

は余分なチューニングなしで良いルックスランダムデータの400の000セットをロードしたいです

+0

ボブをテストしてくれてありがとう。まず、実際には、タイミングを大幅に増加させる26(c1> 5)の文(c1 <5)AND(c2 <7)AND(c3 <1)を得ることができるということです。 2つ目は、mysql-server上の所有者ではないため、データベース設定を変更できないということです。 – aCOSwt

+0

とにかく、400Kサイズのデータ​​ベースでは問題ではありません。テーブルやインデックスが破損している可能性がありますか? 同じスキーマで別のテーブルを作成し、新しいテーブルにデータをコピーしてみてください t1に挿入するa、b、c1、c2、c3、c4、...をtから選択してください。 これは数秒かかります –

+0

既にテーブルとインデックスのどちらも壊れていないと確信しています。しかし、私が得た数字はあなたのものより約10倍高いので、どこか間違ったことを認めています。 – aCOSwt

-1
INDEX(a,b,c1) 

ab彼らは=でテストされているので、最初にする必要があります。次に、cの1つを選択します。すべてのクエリはabの恩恵を受けるでしょう。 1つはさらに利益を得るでしょう。

(最初に来るどのaまたはbを重要ではありません;。パフォーマンスは同じになります)

はい、あなたはそれらの26を持つことができます。多分それは良いです。

4バイトのINTsを1バイトのTINYINT UNSIGNEDに変更します(値は0〜255と仮定します)。

+1

リックありがとうございます。 INTはすでに符号なしのtinyintです。そして、問題は、Bが単一の列ではないということです。それは、B1、B2、B3およびB4とすることができる。したがって、(A、Bi、Cj)合成インデックスを作成すると、4×26インデックスになります。 – aCOSwt

+0

それから4:(A、Bi)だけを使ってください。完璧ではありませんが、あなたが今持っているものよりもうまくいけばいいです。列の意味を説明できる場合は、その意味を何らかの形で利用する回避策を考え出すこともできます。 –

関連する問題