5

group_concatクエリに を追加して、パフォーマンスを低下させました。説明計画は、追加する前と後で同じであるため、これを最適化する方法について混乱しています。

以下は、クエリの簡略化されたバージョンです。

SELECT @curRow := @curRow + 1 AS row_number,
docID,
docTypeID,
CASE WHEN COUNT(1) > 1
     THEN group_concat( makeID )
     -- THEN 'multiple makes found'
     ELSE MIN(makeID)
END AS makeID,
MIN(desc) AS desc
FROM simplified_mysql_table,
(SELECT @curRow := 0) r
GROUP BY docID, docTypeID,
CASE WHEN docTypeID = 1
     THEN 0
     ELSE row_number
END;

CASEのステートメントに注意してくださいSELECTgroup_concat殺しのパフォーマンス。その行にコメントを付けて「複数のmakeが見つかりました」と出力すると、非常に迅速に実行されます。これの原因は何ですか?

4

3 に答える 3

10

このクエリの元の非簡略化バージョンでは、がありましたDISTINCTが、これは完全に不要であり、group_concatでパフォーマンスの問題を引き起こしていました。なぜこのような問題が発生したのかはわかりませんが、削除するとパフォーマンスの問題が修正されました。

于 2012-11-30T18:07:32.613 に答える
3

MySQL では、group_concatパフォーマンスがクエリのパフォーマンスを低下させてはなりません。文字列を含む追加作業であるため、多少の速度低下が予想されます。しかし、10X というよりは 10% のようです。クエリ時間の違いを数値化できますか?

質問: MakeID は文字列ですか、それとも整数ですか? 整数から文字列への変換がパフォーマンスに影響するのではないかと思います。

第二に、の代わりにパフォーマンスはどうなるでしょうconcat(min(MakeId), '-', max(MakedId))group_concat?

第三に、実際のgroup_concat使用DISTINCTまたはORDER BY? これらは、特にメモリが制限された環境では速度が低下する可能性があります。

于 2012-11-29T18:23:16.173 に答える
0

アイデアは、クエリを 2 つの部分に分割することですWHEN docTypeID = 1。1 つは残り用で、もう 1 つは残り用です。

(docTypeID, docID, makeID, desc)最初にインデックスを追加してみてください:

SELECT 
    docID,
    docTypeID,
    CAST(makeID AS CHAR) AS makeID,
    `desc`
FROM 
    simplified_mysql_table,
WHERE 
    NOT docTypeID = 1

UNION ALL

SELECT 
    docID,
    1,
    GROUP_CONCAT( makeID ),
    `desc`                        -- this is not standard SQL
FROM 
    simplified_mysql_table,
WHERE 
    docTypeID = 1
GROUP BY 
    docTypeID,
    docID ;
于 2012-11-29T21:23:36.417 に答える