2016-11-04 9 views
-1

私はLinux上でMariDB 10.1.18を使用しています。グループBy MariaDB very slow

私は次のような構造で簡単なテーブル(t)を持っている:私は主キーが自動的にインデックスされますと仮定し

| id | a | b | c | 
------------------- 
| 1 | 3 | 7 | 10 | 
| 2 | 4 | 6 | 9 | 
| 3 | 2 | 7 | 11 | 
| 4 | 3 | 5 | 10 | 
| 5 | 4 | 8 | 12 | 
| 6 | 2 | 9 | 6 | 


id is primary key 
a - has BTREE index 
b - has HASH index 
c - has HASH index 

。 私のクエリは単純です:パフォーマンスの目的のために

SELECT * FROM t GROUP BY a 

使用されるエンジンはMEMORYです。

500万行では、上記のクエリではが1秒で完了し、は1つのCPUのスレッドを100%利用します。現在、列Aには約150の一意の値があります。

ルーズインデックス検索を使用すると、これが解決できると想定しました。残念ながら、これは決して使用されないため、MariaDBでは動作しないようです。 loosescanはオンに設定されています。

私は私のデータベースに1.1秒かかり

SELECT MAX(a) FROM t GROUP BY a 

を試してみました。

質問:私はこれをすばやくすばやくすることができますか? 0.05秒と同じように。

ありがとうございました!

+0

Plsは説明の結果を投稿します – Shadow

+0

注意点:標準的な開発技術で達成できることはごくわずかです。より高いパフォーマンスを得るためにMySQLインスタンスを設定するようDBAに依頼する必要があるかもしれません。 – Shadow

+0

目的は、特定の行をフィルターに掛けて、aでグループ化された最も高いcを持つ行を戻すことです。例:* DESCによってソートされたIN *(5,6,7)AND IN(2,3)GROUPを選択します。ただし、これにより適切な結果が得られないため、結合が必要です。しかし、私はそれには入りません。 – SilviuT

答えて

0

だから、後に多くの作業と、これは、これまで最速のソリューションですテスト:

  1. 使用メモリーエンジン - それは速くInnoDBのより少なくとも10倍はRAMDISK

  2. メイクに保存されているのですグループ「BY」を使用する代わりに「a」列の要素ごとにクエリを分離し、結果をPHPで結合する
    Ex。 SELECT idからどこにb(3,4,5)AND c(6,7,8)AND a = 1;

  3. このようなINDEX ON(a、b)、INDEX ON(a、c)のような各列の複合インデックスを設定すると、任意のクエリの種類に十分な柔軟性が与えられます。 INDEXESはBTREEでなければなりません。

5ミルのローテーブルの非常に複雑なクエリは、約0.35秒かかります。

0

これは本当に必要なものによって異なります。両方のクエリはそれほど意味をなさない。

SELECT MAX(a) FROM t GROUP BY a 

SELECT a FROM t GROUP BY a 

又は

SELECT DISTINCT a FROM t 

に書き換えることができ、それが "ゼロ" の時間を要します。

最初のクエリはグループごとに最初の行を返します。全テーブル索引がないと仮定すると、idによって順序付けられた最初の行になります。だから、それに相当する「グループごとの最も古いレコードを検索」する、と

select t.* 
from (
    select min(id) as id 
    from t 
    group by a 
) m 
join t using(id) 

に書き換えることができ、また、「時間がない」で実行されます。

しかし

select count(id) as id 
from t 
group by a 

のようなクエリが遅くなります。 SUM()およびAVG()と同じです。これは、エンジンがすべての行を読み取る必要があるためです。 MIN()およびMAX()は、グループごとに1行だけを読み取る必要があります。

私は3.7Mの行と30のグループを持つInnoDBテーブルで同様のクエリをテストしています。

+0

実際にSELECT DISTINCT FROM tは5milの行に対してaproxの0.7秒を要します。 – SilviuT

+0

aからGROUP BYを選択 - aproxも0.7秒かかります。 – SilviuT

+0

30個のグループを持つ3.7M行のInnoDBテーブル(mysql 5.6.21)で私のクエリをテストしました。コピーをMyISAMに変換した後、いくつかのクエリは非常に遅くなりました。だからInnoDBを試してみてください! –